dotNET Framework 1.1
WinXP Pen4 1.7GHz 512MB
Console Application
VS.NET Release
DateTime.Nowの差を計測(精度は15.625msなので注意)
WinXP Pen4 1.7GHz 512MB
Console Application
VS.NET Release
DateTime.Nowの差を計測(精度は15.625msなので注意)
一般的な連結
5回連結 String×3, int×2
TestCode
- string.Concat(str, i, str, i, str);
- new System.Text.StringBuilder([Capacity]).Append(str).Append(i).Append(str).Append(i).Append(str).ToString();
- str + i + str + i + str;
(文字列Length = 30)30万回
| String#Concat | 859ms |
| StringBuilder(Capacityなし) | 1328ms |
| StringBuilder(Capacity = 100) | 1140ms |
| StringBuilder(Capacity = 300) | 1265ms |
| StringBuilder(Capacity = 1000) | 1953ms |
| +演算子(String#Concatに変換されるらしい) | 890ms |
| String#Format | 1781ms |
(文字列Length = 3000)3万回の10倍値
| String#Concat | 23460ms |
| StringBuilder(Capacityなし) | 54840ms |
| StringBuilder(Capacity = 100) | 54210ms |
| StringBuilder(Capacity = 1000) | 55780ms |
| StringBuilder(Capacity = 5000) | 56090ms |
5回連結 String(= new string('a', 30))×5
30万回
| String#Concat | 390ms |
| StringBuilder(Capacityなし) | 1265ms |
| StringBuilder(Capacity = 100) | 1187ms |
| StringBuilder(Capacity = 300) | 1328ms |
| StringBuilder(Capacity = 1000) | 2171ms |
| String#Format | 1343ms |
5000回(!)連結 String(同上)×5000
1000回
| String#Concat | 勘弁してよ(;´Д`) |
| String#Concat(Object[]に代入しこれを引数に) | 2296ms |
| StringBuilder(Capacityなし) | 4781ms |
| StringBuilder(Capacity = 200) | 4140ms |
| StringBuilder(Capacity = 256) | 4718ms |
| StringBuilder(Capacity = 288) | 5218ms |
| StringBuilder(Capacity = 300) | 3281ms |
| StringBuilder(Capacity = 316) | 3036ms |
| StringBuilder(Capacity = 324) | 3234ms |
| StringBuilder(Capacity = 400) | 4109ms |
| StringBuilder(Capacity = 1000) | 4578ms |
| 激しく疑問の残る結果 |
5回連結 int(=65536)×5
30万回
| String#Concat | 1390ms |
| StringBuilder(Capacityなし) | 1780ms |
| StringBuilder(Capacity = 100) | 1750ms |
| StringBuilder(Capacity = 300) | 1937ms |
| StringBuilder(Capacity = 1000) | 2781ms |
| String#Format | 2156ms |
5回連結 long(20桁)×5
30万回
| String#Concat | 2546ms |
| StringBuilder(Capacityなし) | 2578ms |
| StringBuilder(Capacity = 100) | 2250ms |
| StringBuilder(Capacity = 300) | 2562ms |
| StringBuilder(Capacity = 1000) | 3296ms |
| String#Format | 3343ms |
| 以下おまけ |
| Java StringBuffer | 3034ms |
| Java StringBuilder | 3192 ms |
| Java StringBuilder(Capacity = 100) | 2813 ms |
| Perl5.8(join) | 475ms |
| PHP5.1(implode) | 11025ms |
4回連結 String(= new string('a', 30))×4
30万回
| String#Concat | 218ms |
| String#Concat(new string[]に一度代入して引数に) | 281ms |
| StringBuilder(Capacityなし) | 625ms |
| StringBuilder(Capacity = 100) | 562ms |
| StringBuilder(Capacity = 300) | 750ms |
| string#Concatは5つ以上引数を渡すとString[]を生成するとのこと。4つ以下なら生成しない |
| String#Formatは4つ以上引数を渡す場合はobject[]を渡す必要がある。3つ以下なら直接渡すことが出来るが、3つの場合で859msと遅かった |
String#Concatの方法別速度
30万回
| String×5を引数に直接並べる | 390ms |
| String×5をObject[]に代入してそれを引数に指定(配列生成時間含む) | 378ms |
| 生成されるバイナリは同じ(ベンチの意味なし) |
new StringBuilderをループの前に実行
文字列がどんどん長くなっていってしまうため、ループ内でStringBuilder#Length = 0を実行
ちなみにこれを実行しないと100倍以上遅くなった
ちなみにこれを実行しないと100倍以上遅くなった
5回連結 String(= new string('a', 30))×5
30万回
| String#Concat | 390ms |
| StringBuilder(Capacityなし) | 625ms |
| StringBuilder(Capacity = 100) | 546ms |
| StringBuilder(Capacity = 300) | 500ms |
| StringBuilder(Capacity = 1000) | 515ms |
| 以下はループ内にnew StringBuilderを置いた場合(上から引用) |
| StringBuilder(Capacityなし) | 1265ms |
| StringBuilder(Capacity = 100) | 1187ms |
| StringBuilder(Capacity = 300) | 1328ms |
| StringBuilder(Capacity = 1000) | 2171ms |
| 以下おまけ(内部エンコードが2byteでないものは2byteになるように調整した) |
| Java StringBuilder | 1713ms |
| Java StringBuilder(Capacity = 300) | 1172ms |
| Perl5.8(join) | 503ms |
| PHP5.1(implode) | 2553ms |
| C++(単純にstringを+演算子で連結) | 1890ms |
| C(mallocしてstrcat) | 1031ms |
まとめ
- 連結するStringの長さと必要とする時間はほぼ比例する(連結回数が長くない場合)
- 連結する回数が増えると急激に遅くなる
- 基本的にStringBuilderよりString#Concatの方が高速
- (バッファの配列の生成とStringの生成を行う必要があるから当然かも)
- ただし桁の大きい整数型、実数型の連結の場合、それらの文字列型への変換が遅いため、StringBuilderとString#Concatとの差はほとんどなくなる
- StringBuilderのCapacityは指定すべきだが、大きすぎるとかえって遅くなる
- ただし連結する文字列が非常に長い場合、指定してもしなくてもあまり変わらない
- JavaはCapacityなし・ありの差が大きい
- Perlの連結は速い(特にlongの連結)
- PHPは連結、整数型からstringへの変換はともに不得意