ものがたり(旧)

atsushieno.hatenablog.com に続く

パフォーマンス改善は誰の仕事か

文字列探索のアルゴリズムを探していたら、monoのパフォーマンスに関する話を見つけてしまいました。いいですねぇ。こういう実験がもっと見られると面白いなと思います。他のエントリでは純粋なJITの比較に近いことをしているので、JITが遅いっていう結論は変だなと思うのですが、当時monoのI/Oが遅かったのは本当です。ちょうどDickがdaemonless I/Oをコミットした頃に計測しているので、まあ間違いなく遅い方を使っているでしょう…っていうか今気づいたけどmono 1.0で比較してるじゃん…そりゃあ遅いに決まってます。

他にもたまに「MonoはJITが遅い」っていう発言を見かけることがありますが、本当に「JITが遅い」ということの意味を分かった上で発言している人が一体どれだけいるものか、かなり疑問があります(もちろん、JITに最適化の余地があることを否定するものではありませんが)。JITの速度を気にするのは、それこそ僕みたいにCompareInfo実装でabcremとcopypropが有効になってると3%くらい違うのになあとかぼやいている人とか、逆にメモリアロケーションしまくりでgenerational GCじゃないと困るYO!という人くらいだと思うのですよ*1。それ以外はほとんどC#のクラスライブラリコードの速度の問題なので。

ちなみに件のコードではそれ以上にいろんなものを一度に比較しているので、ファイルI/Oの速度だけで10倍違うっていうのはあり得ない話です(ていうか単純なファイルI/Oはそんなに遅くありませんし、遅くなかったはず)。StreamReaderからファイルを読めばEncodingクラス(デフォルトでUTF8)が影響しますし、そもそもJavaのString.indexOf()と.NETのString.IndexOf()は振る舞いが異なるので(まあicuは有効にしていないでしょうから、monoでは実際にはglibの単純文字列検索を行うわけですがいや、mono 1.0ベースならlibicu使ってるなあ)、一様に比較できるわけがないのです。

(その意味ではこちらのエントリの結論にあるBM法やRegexの方は、culture insensitiveなのですから、culture sensitiveなString.IndexOf()より高速なのは当たり前で、比較するならCompareInfo.IndexOf(CompareOptions.Ordinal)でなければならないはずです。)

ん、TB失敗してる。まあいいか…

うーむ、この辺からいろいろ眺めてみたものの、CompareInfoの制約は大きすぎる。曖昧検索のようなものになるし、そもそもtargetと同じ長さの配列を毎回確保するというのは無理がある。

*1:正確にはGCの根本的な相違に比べれば、JITのレベルでのGC種別による違いというのは問題にならないくらい小さいと思いますが