【C#】Enumの爆速ForEach
Enumをforeachで回すと遅いよと聞いて
自前で書いてみたら爆速ForEachができた
// 以下のenum定義を使用する enum Days {Sat=10, Sun=20, Mon, Tue, Wed, Thu, Fri};
まず結果(1,000,000回を回す)
// 1回目 foreach : 1328ms EnumExtension.ForEach : 1283ms EnumExtension.ForEachList : 482ms EnumForEach<T>.Exec : 56ms // 2回目 foreach : 1370ms EnumExtension.ForEach : 1357ms EnumExtension.ForEachList : 635ms EnumForEach<T>.Exec : 61ms // 3回目 foreach : 1342ms EnumExtension.ForEach : 1360ms EnumExtension.ForEachList : 488ms EnumForEach<T>.Exec : 62ms
実装詳細
foreach
普通のforeach
foreach(Days days in Enum.GetValues(typeof(Days))) { }
EnumExtension.ForEach
public static class EnumExtension { public static void ForEach<T>(Action<T> action) where T : struct, IConvertible { var type = typeof(T); foreach(T v in Enum.GetValues(type)) { action((T)v); } } }
// 使い方
EnumExtension.ForEach<Days>( days => {} );
速度がほぼforeachと変わらない
EnumExtension.ForEachList
public static class EnumExtension { public static void ForEachList<T>(Action<T> action) where T : struct, IConvertible { var type = typeof(T); var values = Enum.GetValues(type).Cast<T>().ToList(); var count = values.Count; for(int i = 0 ; i < count ; ++i) { action((T)values[i]); } } }
// 使い方
EnumExtension.ForEachList<Days>( days => {} );
Enum.GetValues(...)してListにキャストする方が遅いと思いきや
まさかかかった時間は半分以下に、ランダムアクセス早い!
EnumForEach.Exec
ジェネリッククラス版:static変数を持ち、反則のチートしてる
public class EnumForEach<T> where T : struct, IConvertible { static List<T> Values = Enum.GetValues(typeof(T)).Cast<T>().ToList(); static int Count = Values.Count; public static void Exec(Action<T> action) { for(int i = 0 ; i < Count ; ++i) { action((T)Values[i]); } } }
// 使い方
EnumForEach<Days>.Exec( days => {} );
爆速!かかった時間はforeachの20分の1以下
最後に
- 測定方法が間違ってないかしら?怖いorz
- 疑念点
- foreachみたいにループ中のbreak脱出はできない
- メモリ消費を考えてない(それほど心配ではないが)
- 俺は普通のforeachを使う(常識を考え百万回を回さないよね)