拡張機能を使用して、以下を機能的なスタイルで記述する方法を見つけたいと思っていました。理想的には、この関数型スタイルは、反復/ループ バージョンと比較してうまく機能します。きっと仕方が無いと思います。おそらく、多くの追加の関数呼び出しとスタック割り当てなどが原因です。
基本的に、面倒なパターンは、Predicate に使用する値を計算し、その計算された値を結果のコレクションの一部として再度必要とすることだと思います。
// This is what is passed to each function.
// Do not assume the array is in order.
var a = (0).To(999999).ToArray().Shuffle();
// Approx times in release mode (on my machine):
// Functional is avg 20ms per call
// Iterative is avg 5ms per call
// Linq is avg 14ms per call
private static List<int> Iterative(int[] a)
{
var squares = new List<int>(a.Length);
for (int i = 0; i < a.Length; i++)
{
var n = a[i];
if (n % 2 == 0)
{
int square = n * n;
if (square < 1000000)
{
squares.Add(square);
}
}
}
return squares;
}
private static List<int> Functional(int[] a)
{
return
a
.Where(x => x % 2 == 0 && x * x < 1000000)
.Select(x => x * x)
.ToList();
}
private static List<int> Linq(int[] a)
{
var squares =
from num in a
where num % 2 == 0 && num * num < 1000000
select num * num;
return squares.ToList();
}