以下のコードは、同じソリューションを実行する 3 つの異なる方法のパフォーマンスをチェックしています。
public static void Main(string[] args)
{
// for loop
{
Stopwatch sw = Stopwatch.StartNew();
int accumulator = 0;
for (int i = 1; i <= 100000000; ++i)
{
accumulator += i;
}
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, accumulator);
}
//Enumerable.Range
{
Stopwatch sw = Stopwatch.StartNew();
var ret = Enumerable.Range(1, 100000000).Aggregate(0, (accumulator, n) => accumulator + n);
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, ret);
}
//self-made IEnumerable<int>
{
Stopwatch sw = Stopwatch.StartNew();
var ret = GetIntRange(1, 100000000).Aggregate(0, (accumulator, n) => accumulator + n);
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, ret);
}
}
private static IEnumerable<int> GetIntRange(int start, int count)
{
int end = start + count;
for (int i = start; i < end; ++i)
{
yield return i;
}
}
}
結果は次のとおりです。
time = 306; result = 987459712
time = 1301; result = 987459712
time = 2860; result = 987459712
Enumerable.Aggregate はより多くのメソッド呼び出しを行うため、「for ループ」が他の 2 つのソリューションよりも高速であることは驚くべきことではありません。しかし、「Enumerable.Range」が「自作の IEnumerable」よりも高速であることに本当に驚きました。Enumerable.Range は単純な GetIntRange メソッドよりも多くのオーバーヘッドがあると思いました。
これにはどのような理由が考えられますか?