foreachのILとループのパターン
糖衣構文としてとても有名なforeachはおおまかに2種類のILになる可能性があります。
- 配列に対するIL(for文とほぼ同等)
- IEnumerable
になる IL
ループだけの速度では前者が約2倍速です。
IEnumerator
実態の型に合わせて最適なコードを選ぶような積極的高速化は行われません。
foreachに渡す物が配列であるか、他のIEnumerable
過度な期待はできません。
さて、最適化というところに主眼を置いてC#を扱う場合、ループを組むときにはおおまかに3通りのパターンがあります。
LINQの内部実装について書いた際に扱ったことがありますが以下の3つです。
- 配列
- List<T> 長さが分かる(且つインデクサが速い)コレクション(←2014/12/6 修正)
- IEnumerable<T> 長さが分からないものの列挙
C#のコンパイラに、型判別と最適なループに展開する属性とかを渡せたらいいのですが。
まあ、この属性を乱用したらループの都度コードが3倍になるわけで、場合によってはキャッシュヒット率の低下などかえって有害。素人にはお勧めできない仕様になってしまいますが。
あと、yield return の展開、次のバージョンではもう少しマシになってるんでしょうか。
まだ確認はしていませんが、期待と不安でいっぱいです。