26

StringBuilder が大きなフラット ファイル (数百 MB) のパターンに一致する行を保存し続けるという条件があります。ただし、条件に達した後、StringBuilder変数の内容をテキストファイルに書き込みます。

ここで、オブジェクトをリセットして同じ変数を使用する必要があるかどうか疑問に思います ->

stringBuilder.delete(0,stringBuilder.length())

また

stringBuilder=new StringBuilder();

パフォーマンスと OOM の問題の両方に関する限り、どちらが優れていると思いますか?

4

8 に答える 8

5

基本的な違いの 1 つは、sb.delete が参照を保持し、コンストラクターがそれを失うことです。

SB がメソッドの引数であり、コンテンツを呼び出し元に戻すために使用されることになっている場合は、sb.delete を使用する必要があります。呼び出し元は元の参照を保持します。

于 2014-01-27T20:02:15.803 に答える
1

私は使うだろう:

 stringBuilder = new StringBuilder();

大量のデータを入力すると、呼び出しstringBuilder.setLength(0);によってバッキング配列の割り当てが解除されないため、メモリ使用量が不必要に高いままになる可能性があります。

また、読みやすく理解しやすいだけです。

于 2013-09-12T14:30:26.987 に答える
1

理想的には、 grepcodenew StringBuilder() から StringBuilder クラスを少し掘り下げて使用する必要があります。

新しいオブジェクトの作成:

/**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

new StringBuilder() は、初期容量の char 配列を持つ新しいオブジェクトを作成します。オーバーヘッド: 古いオブジェクトをクリアするために GC が呼び出されます。

delete の使用:

public AbstractStringBuilder delete(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            end = count;
        if (start > end)
            throw new StringIndexOutOfBoundsException();
        int len = end - start;
        if (len > 0) {
            System.arraycopy(value, start+len, value, start, count-end);
            count -= len;
        }
        return this;
    }

長さと TrimToSize の使用:

public void trimToSize() {
        if (count < value.length) {
            value = Arrays.copyOf(value, count);
        }
    }

配列クラスからcopyOfを呼び出します

public static char[] copyOf(char[] original, int newLength) { char[] copy = new char[newLength]; System.arraycopy(元、0、コピー、0、Math.min(元の長さ、新しい長さ)); コピーを返す; }

これで、ネイティブ メソッドであるSystem.arrayCopyも呼び出されます。copyOf を見ると、長さ 0 の新しい charArray が再び作成されており、それにデータを再度追加しようとすると、現在の長さが 0 になるため、expand が呼び出されます。したがって、 new StringBuilder() を呼び出すほうがよいと思います

上記のコードはgrepcodeで確認できます

PS : @ user3241961 は、このオブジェクトの参照を使用している場合に書き込みます。新しい場合は、再度設定する必要があります。

于 2015-07-29T13:11:35.433 に答える
0

タイトなループに陥っていて、データをファイルに書き込んだ後もそのループに戻る場合は、StringBuilder を確実に再利用する必要があります。そうしない理由はなく、GC をかき回すよりはましです。これを C または C++ で記述している場合は、バッファーを再利用します。

また、delete(...) メソッドが System.arraycopy を呼び出すことは事実ですが、コピーされたバイト数は 0 であるため、重要ではありません。

ああ、他の誰かが、バッファを再利用する最速の方法である setLength(...) メソッドがあると私に言いました。

于 2013-09-12T14:37:39.497 に答える