普段は業務システムを扱うので、ありがちな処理を題材に.NET6の練習もかねて、ベンチマークとってみます。
題材はshift-jis形式で、明細10行を1行で表現するといった業の深い形式のデータを読み込んで、CSVっぽい何かに変換する処理です。(変換先もヘッダとフッタを含む大福帳的なデータを想定しています)
https://github.com/panda728/ImportingProcess/blob/master/ImportingProcess/data01.txt
(指摘を受けてMemoryStream上で読み書きするように変更)
まずは素直にStreamReaderで読み込んで、クラスに展開してから、ファイル出力します。
https://github.com/panda728/ImportingProcess/blob/master/ImportingProcess/Import01.cs
Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
BaselineAsync | 733.4 ms | 177.0 ms | 9.70 ms | 1.00 | 0.00 | 51000.0000 | 17000.0000 | 4000.0000 | 375 MB |
SpanCharAsync | 727.9 ms | 178.0 ms | 9.76 ms | 0.99 | 0.02 | 50000.0000 | 16000.0000 | 4000.0000 | 370 MB |
YieldReturnAsync | 325.7 ms | 160.3 ms | 8.79 ms | 0.44 | 0.01 | 65000.0000 | 2000.0000 | 2000.0000 | 362 MB |
StringBuilderAsync | 366.8 ms | 124.9 ms | 6.84 ms | 0.50 | 0.01 | 88000.0000 | 2000.0000 | 2000.0000 | 452 MB |
変換結果をListに格納(BaselineAsync)する方式と、yield return する方式(YieldReturnAsync)の差がよく表れていますね。
stringを直接渡さないで済むような引数が増えたので、SpanCharAsync で試してみました。少しの手間でいい感じに効果がでてますね。
StringBuilderAsync では、書き込み前の文字列組立てをStringBuilderに変えてみたのだけど、なぜか無駄に処理が増えただけでした。
今後はバイナリで直接扱ってみたいですね。