【发布时间】:2016-09-12 05:43:53
【问题描述】:
我正在查看 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 个字符长?这个猜测有什么用?
【问题讨论】:
-
我不知道,但我猜 16 只是对平均预期大小的猜测。听起来很适合我通常需要它的用例。请记住,StringBuilder 无论如何都会被 GC 处理,所以它是否有点太大也没关系。节省调整大小很好,因为调整大小需要复制整个先前的数组;在最坏的情况下,如果您每次都调整大小,那么您将获得 o(n^2) 的性能。
标签: java string performance apache-stringutils