そのため、基本的に文字列を追加して処理する方法は、混乱とリソースの浪費を引き起こすため、他の方法に置き換えられています。同意しますが、このリソースの浪費の原因を正確に知りたいです...ここで述べたように。
「..そして、文字列を処理するための洗練されたコードを持たない実装で実行していると、多くの無駄な割り当てを行うことになります...」 文字列バッファメソッドがこの無駄を回避する方法をリンクしてください...
そのため、基本的に文字列を追加して処理する方法は、混乱とリソースの浪費を引き起こすため、他の方法に置き換えられています。同意しますが、このリソースの浪費の原因を正確に知りたいです...ここで述べたように。
「..そして、文字列を処理するための洗練されたコードを持たない実装で実行していると、多くの無駄な割り当てを行うことになります...」 文字列バッファメソッドがこの無駄を回避する方法をリンクしてください...
これについての私の説明は、Java / .NET のバックグラウンドから来ていますが、同じ論理が適用されます。
1.可変オブジェクトと不変オブジェクトの概念を学ぶ必要があります...
Int32 / Integer などのオブジェクトは可変オブジェクトです。つまり、インスタンス化後に現在のメモリ位置で変更できます。これは、オブジェクトの値に関係なく、メモリ内のサイズを変更する必要がないためです。
文字列は不変オブジェクトです。つまり、いったん割り当てられると、現在のメモリ位置で変更することはできません。これは、本来、文字列の長さが任意であるため、文字列の長さが変わるたびに、システム/ランタイムは文字列を格納するメモリ内の新しい場所を見つける必要があるためです。
2. 連結 vs. StringBuilder / StringBuffer
文字列は不変であるため、連結ごとにメモリの再割り当てが強制されます。次の例では ASCII エンコーディング (1 文字あたり 1 バイト) を使用しているとします。
var message = "Hello World";
この時点で、システムは文字列を格納するために 11 バイトのメモリを割り当てました。
message += "Hello Universe";
この時点で、システムは元の文字列にさらに 14 バイトを割り当てる必要があります。既存の 11 バイトのメモリでは、新しい文字列を保存できません!
「文字列を処理するための洗練されたコード」 ( StringBuffer
/ ) が役立つ理由StringBuilder
!
文字列をバッファ/ビルダーに追加するたびに、メモリが一度割り当てられ、その文字列へのポインタがメモリに保持されます。次に文字列を割り当てるときは、最後の場所に影響を与えることなく、新しい場所でそれを行います。文字列の構築が完了すると、バッファー/ビルダーはすべてを一度に連結して単一の文字列にします。したがって、バッファー/ビルダーに何かを追加するたびにそれを行うわけではないため、文字列の割り当てが大幅に削減されます!
例:
StringBuilder builder = new StringBuilder();
builder.Append("Hello World");
この時点で、ビルダーは 11 バイトを割り当て、その割り当てをそのままにします!
builder.Append("Hello Universe");
この時点で、ビルダーはさらに 14 バイトを割り当て、最後の文字列をそのまま残しました。
builder.ToString();
この時点で、ビルダーはメモリ内のすべての文字列を 1 つの文字列に連結します!
概要:
次の理由により、連結はリソースの無駄です。
システム/ランタイムは、参照解除された古いメモリ ロケーションを一掃する必要があります。これには、CPU 時間がかかります。Java/.NET では、ガベージ コレクションと呼ばれます。
ガベージ コレクタが移動してメモリを一掃できるようになるまで、メモリを再割り当てするたびに無駄になります。
したがって、連結は CPU とメモリ使用量のパフォーマンスを低下させます。