注意
きちんとしたテストをしようと思ったのですが、途中でめんどくさくなりました。 条件を揃えたり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紙がない世界に転生してしまう 。