はじめに
Qiita初投稿です。
普段はUntiyでゲーム開発したりしている情報系B3です。
foreachとList.ForEach()メソッドではパフォーマンスがどれぐらい変化するか気になりましたが、特に比較されている文献が見つからなかったので。自分で比較してみました。
今回は Visual Studio + .NETコンソールアプリケーション上での計測となります。
計測
0から200000までの数が入ったリストを用意してそれぞれの要素を2乗したリストを作る処理で計測していきたいと思います。
計測対象は、
- ノーマルなfor文 (indexで回すやつ)
- foreach文
- List.ForEach()メソッド
- LinqのSelect
です。
Program.cs
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
static List<int> numList;
static Stopwatch sw = new Stopwatch();
static void Main(string[] args)
{
numList = Enumerable.Range(0, 200000).ToList();
Console.WriteLine("ノーマルなfor文");
CountProcessTime(NormalFor);
Console.WriteLine("foreach文");
CountProcessTime(ForEachProcess);
Console.WriteLine("List<T>.ForEach()メソッド");
CountProcessTime(LambdaForEach);
Console.WriteLine("Linqでの処理");
CountProcessTime(LinqProcess);
}
static void CountProcessTime(Action process)
{
sw.Start();
process();
sw.Stop();
var ts = sw.Elapsed;
Console.WriteLine($" {ts}");
Console.WriteLine($" {ts.Hours}h {ts.Minutes}m {ts.Seconds}s {ts.Milliseconds}ms");
}
static void NormalFor()
{
List<int> squareList = new List<int>();
for (int i = 0; i < numList.Count; i++) squareList.Add(numList[i] * numList[i]);
}
static void ForEachProcess()
{
List<int> squareList = new List<int>();
foreach (var num in numList) squareList.Add(num * num);
}
static void LambdaForEach()
{
List<int> squareList = new List<int>();
numList.ForEach(num => squareList.Add(num * num));
}
static void LinqProcess()
{
List<int> squareList = new List<int>();
squareList = numList.Select(num => num * num).ToList();
}
}
では実行してみましょう。
結果
コンソール出力
ノーマルなfor文
00:00:00.0036469
0h 0m 0s 3ms
foreach文
00:00:00.0059512
0h 0m 0s 5ms
List<T>.ForEach()メソッド
00:00:00.0106280
0h 0m 0s 10ms
Linqでの処理
00:00:00.0179167
0h 0m 0s 17ms
indexで回すfor | foreach | List.ForEach()メソッド | LinqのSelect | |
---|---|---|---|---|
処理時間 | 3.65ms | 5.95ms | 10.62ms | 17.91ms |
今回の主題である、foreach文とList.ForEach()メソッドでは約2倍程度パフォーマンスが異なるという結果を得られました。
(環境が違えば効率もまた大きく異なると思われます。)
まぁぶっちゃけ問題ない範囲だと思うので、両者の使用感が変わるなどといったことは特にありませんが...
そのうちUnityでの比較もやってみたいと思います