3

我正在查看 Apache CommonsStringUtils.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 个字符长?这个猜测有什么用?
4

3 回答 3

1

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

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

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

于 2016-05-17T17:31:52.863 回答
0

真的......这不仅仅是16您在 Question 中所说的硬编码。

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

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 包含 at index 的元素,startIndex则默认内存分配将是lengththat Object

谢谢你。

于 2016-05-16T12:50:15.343 回答
0

嗯..StringUtils.join制作OutOfMemory Exception大数组...;你知道这个案子。

于 2020-05-16T20:29:27.900 回答