2011-07-11 26 views
6

私はここ1ヶ月間、仕事中にいくつかのプログラムを開発していますが、これは多くの文字列解析などが行われています。私はchar配列がより速いので、文字列ではなく、このようなもののためのchar配列を使用することをお勧めしました。なぜ文字配列が高速であるのか理解していますが、文字列型の方が遅くなるのはなぜですか?どのようなデータ構造が実装されていますか?char配列と同じ速さにする方法はありますか?文字列型.NET対文字配列

答えて

13

最も顕著な違いは、stringが不変であることです。したがって、その一部を変更することはできず、それぞれの変更で完全に新しいコピーを作成する必要があります。

文字列自体は非常に特殊な実装(可変サイズクラス)を持ち、配列に裏打ちされていません。文字列内のcharへの読み取り専用アクセスが遅くなる理由はありません。

文字列の小さな部分を変更する場合は、StringBuilderまたはchar[]のいずれかを使用する必要があります。この2つのうちchar[]は、StringBuilderに追加の検証と迂回があるため、より高速です。しかし、これは実装の詳細なので、最後にテストしてから変更されている可能性があります。


はちょうどそれをベンチマーク、および.NET 4のよう char[]のメンバーが StringBuilderに比べて約4倍の速さで設定します。しかし、どちらも毎秒200百万を超える割り当てを行うことができますので、実際にはほとんど問題になりません。

char[]からの読み取りは、stringからの読み取りよりわずかに高速です(私のテストコードでは25%)。一方、StringBuilderからの読取りは、char[]からの読取りよりも遅い(係数3)。

すべてのベンチマークで私は他のコードのオーバーヘッドを無視しました。つまり、私のテストでは少し違いが過小評価されています。

私の結論は、char[]が選択肢より高速ですが、毎秒数百メガバイトを超える場合にのみ問題になります。


//Write StringBuilder 
StringBuilder sb = new StringBuilder(); 
sb.Length = 256; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sb[j] = 'A'; 
} 

//Write char[] 
char[] cs = new char[256]; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    cs[j] = 'A'; 
} 

// Read string 
string s = new String('A',256); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

//Read char[] 
char[] s = new String('A',256).ToCharArray(); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

//Read StringBuilder 
StringBuilder s= new StringBuilder(new String('A',256)); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

(はい、私は私のベンチマークコードは非常に良いではないですけど、私はそれは大きな違いがないと思います。)

+0

文字列とパフォーマンスの向上は、メモリの面でありますすべての弦が拘束されているためです。 – koumides

+0

@koumides明示的にインターンされた文字列リテラルと文字列のみがインターンされます。 – CodesInChaos

1

文字配列に対するchar配列の利点は、文字配列をその場で変更できることです。 C#の文字列は不変であるため、変更すると、変更されたバージョンの文字列で新しいオブジェクトがヒープ上に作成されます。 char配列では、ヒープ上に何も配置せずにたくさんの変更を加えることができます。