Amosapientiam

https://yuchiki.github.io/

LINQ遅くなさそう

注意

きちんとしたテストをしようと思ったのですが、途中でめんどくさくなりました。 条件を揃えたりILを読んだりしてないので余り意味はないかもしれませんが、結果だけここにおいときます。

結論

  • きちんとわかったこと
    • とくにないです
  • なんとなく思ったこと
    • LINQはボケーっと書くと確かにforより遅くなる
    • ちょっと工夫すればforやwhileと比べて遅くならないこともある?
    • debugビルドとreleaseビルドではそこまで速度の差が出ない
    • optimizationを有効にしないと悲惨

実験内容

以下の処理をする関数を幾つかの方法で書き、速度を比較。

処理

  • 与えられた整数列から
  • 十進表記中に"3"を含むものを除き
  • 5の倍数を除き
  • 十進表記中に現れる"57"を"91"に書き換え
  • 7の倍数を除き
  • その数から始まるコラッツ列が1に到達するまでの長さを求め
  • その和を返す

比較項目

  • LINQ/For文のどちらを使うか
  • Parallelにするかしないか
  • Optimizationを有効にするかしないか
  • 与えられた仕様を素朴に書き下すか/やや工夫するか

などの条件を変えて実行時間を比較。

条件

  • プログラム
    • github.com
    • 引数の整数列の長さ: 10000000
    • 5回テストして実行時間の平均を採用
    • 比較する関数が同じ値を返すっぽいことは dotnet testで確認
  • ビルドコマンド
    • dotnet build
  • 環境

実験結果

以下値はいずれも[秒]。 debugとreleaseの差はほとんどなかったので一部割愛。

素朴な実装のとき

Method Debug + Unoptimized Release+Optimized
LINQ 30.55 12.66
For文 24.13 06.89
ParallelLinq 13.69 05.76
ParallelFor 40.89 15.55

やや工夫したとき

Method Debug + Unoptimized Release+Optimized
LINQ 23.01 06.88
For文 23.10 07.20
ParallelLinq 13.45 05.43
ParallelFor 11.07 04.71

ちゃんとした比較実験にするためにしなければならないこと

  • 各メソッドの内容をきちんと考える。何を固定して何を動かすのか
  • IL(.netの中間言語)を読んで議論する

思ったこと

無駄の多いコードを書くと来世はきらら系4紙がない世界に転生してしまう 。