LINQと従来手法のパフォーマンス比較
LINQクエリはコレクション操作を簡潔かつ可読性高く記述するための強力な機能ですが、その利便性にはパフォーマンスコストが伴います。本記事では、基本的なLINQ操作(Where、Select)と同等の非LINQコード、さらに最適化された手動実装の性能比較を行います。
比較対象の実装方法
比較対象となる3つの実装パターン:
- LINQ実装:標準のLINQ拡張メソッドを使用
- 汎用実装:foreachループを使用した一般的な実装
- 手動最適化実装:特定の型と条件に特化した高速実装
LINQ実装サンプル
// WhereのLINQ実装
private List<TElement> ExecuteLinqWhere<TElement>(
IEnumerable<TElement> source,
Func<TElement, bool> condition)
{
return source.Where(condition).ToList();
}
// SelectのLINQ実装
private List<TResult> ExecuteLinqSelect<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, TResult> converter)
{
return source.Select(converter).ToList();
}
汎用実装サンプル
// Whereの汎用実装
private List<TElement> ExecuteGenericWhere<TElement>(
IEnumerable<TElement> source,
Func<TElement, bool> condition)
{
var matchingElements = new List<TElement>();
foreach (var item in source)
{
if (condition(item))
{
matchingElements.Add(item);
}
}
return matchingElements;
}
// Selectの汎用実装
private List<TResult> ExecuteGenericSelect<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, TResult> converter)
{
var convertedElements = new List<TResult>();
foreach (var item in source)
{
convertedElements.Add(converter(item));
}
return convertedElements;
}
手動最適化実装サンプル
// Whereの手動最適化実装
private List<int> ExecuteManualWhere(int[] numbers)
{
var matchingNumbers = new List<int>();
for (int index = 0; index < numbers.Length; index++)
{
if (numbers[index] == 1)
{
matchingNumbers.Add(numbers[index]);
}
}
return matchingNumbers;
}
// Selectの手動最適化実装
private int[] ExecuteManualSelect(int[] numbers)
{
var convertedNumbers = new int[numbers.Length];
for (int index = 0; index < numbers.Length; index++)
{
convertedNumbers[index] = numbers[index] * 2;
}
return convertedNumbers;
}
ベンチマーク環境と結果
1024要素の配列を使用し、各実装を10000回実行して処理時間を計測:
| テスト | 手動実装(ms) | 汎用実装(ms) | LINQ実装(ms) |
|---|---|---|---|
| Where | 55 | 402 | 93 |
| Select | 83 | 592 | 199 |
テスト環境:Unity 2021.3.29、2024年2月実施
考察と結論
最新のLINQ実装は大幅な性能向上が見られ、汎用的なforeach実装と比較して明確な優位性を示しています。ただし、型とアルゴリズムを特定した手動最適化実装には性能面で及びません。
LINQを使用する際の実践的な指針:
- 可読性と保守性が重要な場合はLINQを優先
- クリティカルなパフォーマンスが要求される場面では手動最適化を検討
- 最新の.NET環境ではLINQの性能は十分実用的