首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >理解StringUtils.join性能决策

理解StringUtils.join性能决策
EN

Stack Overflow用户
提问于 2016-05-16 12:22:25
回答 3查看 1.3K关注 0票数 3

我在研究Apache的StringUtils.join方法的实现时,无意中发现了一条我认为是为了性能的行,但我不明白为什么他们会以这种方式使用这些特定的值。

以下是实现:

代码语言:javascript
运行
复制
public static String join(Object[] array, String separator, int startIndex, int endIndex) {
    if (array == null) {
        return null;
    }
    if (separator == null) {
        separator = EMPTY;
    }

    // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
    //           (Assuming that all Strings are roughly equally long)
    int noOfItems = (endIndex - startIndex);
    if (noOfItems <= 0) {
        return EMPTY;
    }

    StringBuilder buf = new StringBuilder(noOfItems * 16); // THE QUESTION'S ABOUT THIS LINE

    for (int i = startIndex; i < endIndex; i++) {
        if (i > startIndex) {
            buf.append(separator);
        }
        if (array[i] != null) {
            buf.append(array[i]);
        }
    }
    return buf.toString();
}

我的问题是关于StringBuilder buf = new StringBuilder(noOfItems * 16);线的:

  • 我假设给StringBuilder一个初始容量目标性能,所以在构建字符串时需要更少的调整。我的问题是:这些调整大小的操作实际上对性能有多大影响?这种策略在速度上真的提高了效率吗?(因为就空间而言,如果分配的空间超过必要,甚至可能为负数)
  • 为什么使用神奇的数字16?为什么他们会假设数组中的每个String都有16个字符长?这个猜测有什么用?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-17 17:31:52

16是对带有分隔符的字符串的预期平均大小的略微高估(大概是基于经验/统计)。

预先分配足够的空间来保存整个结果,避免在执行过程中用更大的(双倍大小)数组替换支持数组,并复制元素(这是O(n)操作)。

如果在大多数情况下避免了替换操作,即使过高估计,分配一个更大的数组也是值得的。

票数 1
EN

Stack Overflow用户

发布于 2016-05-16 12:50:15

真的..。这并不是你在问题中所说的唯一硬编码的16

如果你再查一遍这个定义。你会发现这样的东西。

代码语言:javascript
运行
复制
bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length())
                        + separator.length());  
     //16 will only assigned if Object array at position StartIndex contains null.

        StringBuffer buf = new StringBuffer(bufSize); //if null then default memory allocation for String Buffer will be 16 only.

在这里,StringBuffer将调用构造函数,该构造函数将作为

代码语言:javascript
运行
复制
     new StringBuffer(int Capacity);
Constructs a string buffer with no characters in it and the specified initial capacity.

如果Object包含at索引startIndex的元素,那么默认的内存分配将是该Objectlength

谢谢。

票数 0
EN

Stack Overflow用户

发布于 2020-05-16 20:29:27

嗯..。StringUtils.join在大数组中生成OutOfMemory Exception .;您知道这种情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37253848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档