3

私は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 文字の長さであると想定するのでしょうか? この推測は何の役に立つでしょうか?
4

3 に答える 3

1

16セパレータ付きの文字列の予想される平均サイズのわずかな過大評価 (おそらく経験/統計に基づく) です。

結果全体を保持するのに十分なスペースを事前に割り当てることで、実行中にバッキング配列をより大きな (サイズが 2 倍の) 配列に置き換え、要素をコピーする (これは O(n) 操作です) ことを回避できます。

ほとんどの状況で置換操作を回避するのであれば、より大きな配列を割り当てるためにかなりの過大評価をしても、コストに見合うだけの価値があります。

于 2016-05-17T17:31:52.863 に答える
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 に at index の要素が含まれている場合startIndex、デフォルトのメモリ割り当てはlengthそのになりObjectます。

ありがとうございました。

于 2016-05-16T12:50:15.343 に答える