C#で配列やリストをforとforeachで走査する際の速度比較

先日、コードの速度チューニングを行ったのですが、
その際にC#ではforeach文よりもfor文の方が速いという話を思い出して、
書き換えを行う前に調査してみました。

次の記事を参考に速度調査させていただきました。ありがとうございます。
forとforeachのアクセス速度比較 – Qiita

個人的な結論としては、以下のようになりました。
・リスト使用時はfor文が速い(要素へのアクセスには注意)
・配列使用時はforeach文が速い
・リストよりも配列の方が速い
なので、カリカリにチューニングしたい場合は配列+foreachが良いのかもしれません。
(そこまでする必要がある場合は、実際のコードで速度比較して決定した方が良さそうです)

それぞれの速度比較は以下です。(処理時間は末尾に記載)

・リスト使用時の速度
for文(一時キャッシュあり)> ForEachメソッド > foreach文 >>> for文(一時キャッシュなし)
・配列使用時の速度
foreach文 > for文(一時キャッシュあり)> for文(一時キャッシュなし)

調査してわかったこと・わからなかったことは以下です。
・Listの値へのインデクサでのアクセスはその都度個数チェックが発生するので、
 何度も使う場合遅い。一時変数にキャッシュすべし。
・ListのEnumeratorでは個数以外のチェックも行っているので、
 個数チェックだけのfor文やArrayのEnumeratorより遅い
・配列の場合に、for文よりもforeachの方が速い理由は不明
 (個数へのアクセスが内部フィールドな分速いとか?)

処理速度を調査するにあたり
参考にさせていただいだ記事中のコードに以下のようなコードを追記し、
リストと配列の2パターン用意してテストしました。

for (var i = 0; i < testlist.Count; i++) {
	var value = testlist[i]; // 一時変数にキャッシュ
	for (var cnt = 0; cnt < 1000; cnt++) {
		buf = value;
	}
}

それぞれの処理時間は以下です。10回平均です。
(tmp = 一時キャッシュあり)

By List
for Loop : 204 ms
for Loop tmp : 79.5 ms
foreach Loop : 82.7 ms
ForEach Loop : 81.8 ms

By Array
for Loop : 67.8 ms
for Loop tmp : 50.7 ms
foreach Loop : 49.7 ms

以上です。

コメントを残す