kazuk は null に触れてしまった
C# / .NET 系技術ネタ縛りでお送りしております
タグアーカイブ: CLR4
.NET CLR2 と CLR4 の StringBuilder のパフォーマンス
2010/12/07
投稿者: : 以下コードにより計測
class Program { static void Main(string[] args) { Random rnd = new Random(); Console.WriteLine("Hit enter to start"); Console.ReadLine(); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < 10000; i++) { // 64KB のテキストをランダム文字で生成 StringBuilder sb = new StringBuilder(); while (sb.Length < 65535) { sb.Append('a' + rnd.Next(26)); } } stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedTicks); Console.ReadLine(); } } まずCLR2 での結果
Hit enter to start
891252599
約90秒程度で完了、その時の特にメモリ系の挙動を PerfMon でとったスクリーンショットの注目点を以下。
CLR2 – #Gen1 Collections
CLR2 – #Gen2 Collections
これが全く同一値という世代別GCにとっては悪夢のシチュエーション。
CLR2 – Large Object Heap Size
LOH の上下からLOHのガベージコレクションが走っている事が解る
CLR2 – % Time in GC
LOH の下がるタイミングで %Time in GC にピンがたっている。
続いてCLR4での結果
Hit enter to start
662106546
数値としては 134%、
パフォーマンスカウンタの差異はこんな感じ
CLR4 – #Gen 1 Collections
CLR4 – #Gen 2 Collections
なんと Gen 2コレクションの発生0。
CLR4 – Large Object Heap Size
LOH もべったり。
CLR4 – % Time in GC
#Gen 1 Collectionsの簡易GCで済むので、コストも低い。
結論、個々のシステムの特性によって感応度に違いはあるかも知れないけど、比較的大きな文字列を編集処理してる場合には CLR2 に対してCLR4の StringBuilder は約3割高速で、主因はStringBuilder内部でのバッファ方式の変更による物。
ReSharper による CLR2 のStringBuilder定義表示
m_StringValue に実体が入ってるので、20KBを超えるとLOH行き、しかもvolatileというCPUに優しくない存在。
同じく ReSharper による CLR4 のStringBuilder 定義表示
m_ChunkPrevious によってチャンク化されていて m_ChunkChars に実体が分割して持たれるという構造、分割されたそれぞれは 8000文字まで、要するに16KBなのでLOHには絶対に行かない。
結論
素晴らしい!アプリケーションをCLR2からCLR4にするだけで数十%のパフォーマンス向上も夢じゃないよね。
#夏ぐらいから気付いてたんだけど、正確に分析したくなったので測定してみましたなブログ。