了解StringUtils.join性能决策

时间:2016-05-16 12:22:25

标签: java string performance apache-stringutils

我正在研究Apache Commons'的实现。 StringUtils.join方法并偶然发现了一条线,我认为这是为了表现,但我不明白为什么他们按原样行事,具有这些特定价值。

以下是实施:

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个字符?这个猜测有什么用呢?

3 个答案:

答案 0 :(得分:1)

16略微高估了(可能基于经验/统计数据)预期的字符串分隔符的平均大小。

预先分配足够的空间来保存整个结果,避免在执行期间用更大(两倍大小)的数组替换后备阵列并复制元素(这是一个O(n)操作)。

如果在大多数情况下避免更换操作,过度估计(即使相当多)分配更大的阵列也是值得的。

答案 1 :(得分:0)

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

如果再次查看定义。你会发现这样的东西。

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将调用构造函数,该构造函数将作为

提供
     new StringBuffer(int Capacity);
Constructs a string buffer with no characters in it and the specified initial capacity.

如果Object Array包含索引为startIndex的元素,那么默认的memomy分配将为length的{​​{1}}。

谢谢。

答案 2 :(得分:0)

hmm .. StringUtils.join做成OutOfMemory Exception大阵列...; 你知道这种情况。