Java 了解StringUtils.join性能决策
我在研究ApacheCommons的StringUtils.join方法的实现时,偶然发现了一行我认为是为了提高性能的代码,但我不明白他们为什么用这些特定的值这样做 以下是实现:Java 了解StringUtils.join性能决策,java,string,performance,apache-stringutils,Java,String,Performance,Apache Stringutils,我在研究ApacheCommons的StringUtils.join方法的实现时,偶然发现了一行我认为是为了提高性能的代码,但我不明白他们为什么用这些特定的值这样做 以下是实现: public static String join(Object[] array, String separator, int startIndex, int endIndex) { if (array == null) { return null; } if (separato
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();
}
公共静态字符串联接(对象[]数组、字符串分隔符、int-startIndex、int-endIndex){
if(数组==null){
返回null;
}
if(分隔符==null){
分隔符=空;
}
//endIndex-startIndex>0:Len=NofStrings*(Len(第一个字符串)+Len(分隔符))
//(假设所有字符串的长度大致相等)
int noOfItems=(endIndex-startIndex);
如果(noOfItems真的……这不是你在问题中所说的唯一的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.
如果对象数组包含at indexstartIndex
的元素,则默认的备忘分配将是该对象的length
谢谢。16
略微高估了带分隔符的字符串的预期平均大小(可能基于经验/统计数据)
预先分配足够的空间来保存整个结果,可以避免在执行过程中使用更大(大小的两倍)的数组替换备份数组并在元素上进行复制(这是一个O(n)操作)
如果在大多数情况下避免了替换操作,那么高估分配更大数组的成本是值得的,即使高估了一点。hmm..StringUtils.join
makeOutOfMemory Exception
在大数组中。。。;
你知道这种情况。我不知道,但我猜16只是对平均预期大小的猜测。听起来对于我通常需要它的用例来说是正确的。请记住,StringBuilder将在一段时间内完成GC,所以它是否有点太大并不重要。节省调整大小很好,因为调整大小需要复制覆盖整个前一个数组;在最坏的情况下,如果每次调整大小,则性能为o(n^2)。