Я предположил, что лямбда-функции
, делегаты
и анонимные функции
с одним и тем же телом будут иметь одинаковую «скорость», однако при выполнении следующая простая программа:
static void Main(string[] args)
{
List<int> items = new List<int>();
Random random = new Random();
for (int i = 0; i < 10000000; i++)
{
items.Add(random.Next());
}
Stopwatch watch;
IEnumerable<int> result;
Func<int, bool> @delegate = delegate(int i)
{
return i < 500;
};
watch = Stopwatch.StartNew();
result = items.Where(@delegate);
watch.Stop();
Console.WriteLine("Delegate: {0}", watch.Elapsed.TotalMilliseconds);
Func<int, bool> lambda = i => i < 500;
watch = Stopwatch.StartNew();
result = items.Where(lambda);
watch.Stop();
Console.WriteLine("Lambda: {0}", watch.Elapsed.TotalMilliseconds);
watch = Stopwatch.StartNew();
result = items.Where(i => i < 500);
watch.Stop();
Console.WriteLine("Inline: {0}", watch.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
Я получаю:
Делегат: 4,2948 мс
Лямбда: 0,0019 мс
Анонимный: 0,0034 мс
Хотя и незначительно, почему эти три - очевидно идентичных - метода работают в разных скорости? Что происходит под капотом?
Обновление:
Как предполагается в комментариях, следующее «принудительно» вызывает Where
, вызывая для него ToList ()
. Кроме того, добавлен цикл, предлагающий больше данных выполнения:
while (true)
{
List<int> items = new List<int>();
Random random = new Random();
for (int i = 0; i < 10000000; i++)
{
items.Add(random.Next());
}
Stopwatch watch;
IEnumerable<int> result;
Func<int, bool> @delegate = delegate(int i)
{
return i < 500;
};
watch = Stopwatch.StartNew();
result = items.Where(@delegate).ToList();
watch.Stop();
Console.WriteLine("Delegate: {0}", watch.Elapsed.TotalMilliseconds);
Func<int, bool> lambda = i => i < 500;
watch = Stopwatch.StartNew();
result = items.Where(lambda).ToList();
watch.Stop();
Console.WriteLine("Lambda: {0}", watch.Elapsed.TotalMilliseconds);
watch = Stopwatch.StartNew();
result = items.Where(i => i < 500).ToList();
watch.Stop();
Console.WriteLine("Inline: {0}", watch.Elapsed.TotalMilliseconds);
Console.WriteLine(new string('-', 12));
}
Приведенный выше код дает ~ 120 мс для каждой функции.