Лямбда-выражение является анонимной функцией.«Анонимная функция» относится либо к лямбда-выражению, либо к анонимному методу (это то, что вы назвали «делегатом» в своем коде).
Все три операции используют делегаты.Второй и третий используют лямбда-выражения.Все три будут работать одинаково, с одинаковыми характеристиками производительности.
Обратите внимание, что может иметь разницу в производительности между:
Func<int, int> func = x => ...;
for (int i = 0; i < 10000; i++) {
CallFunc(func);
}
и
for (int i = 0; i < 10000; i++) {
CallFunc(x => ...) // Same lambda as before
}
Это зависит от того, может ли компилятор кэшировать делегат, созданный лямбда-выражением.Это, в свою очередь, будет зависеть от того, захватывает ли он переменные и т. Д.
Например, рассмотрим следующий код:
using System;
using System.Diagnostics;
class Test
{
const int Iterations = 1000000000;
static void Main()
{
AllocateOnce();
AllocateInLoop();
}
static void AllocateOnce()
{
int x = 10;
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
Func<int, int> allocateOnce = y => y + x;
for (int i = 0; i < Iterations; i++)
{
sum += Apply(i, allocateOnce);
}
sw.Stop();
Console.WriteLine("Allocated once: {0}ms", sw.ElapsedMilliseconds);
}
static void AllocateInLoop()
{
int x = 10;
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
for (int i = 0; i < Iterations; i++)
{
sum += Apply(i, y => y + x);
}
sw.Stop();
Console.WriteLine("Allocated in loop: {0}ms", sw.ElapsedMilliseconds);
}
static int Apply(int loopCounter, Func<int, int> func)
{
return func(loopCounter);
}
}
Компилятор умен, но есть разница.Используя Reflector, мы можем видеть, что AllocateInLoop
эффективно компилируется в:
private static void AllocateInLoop()
{
Func<int, int> func = null;
int x = 10;
Stopwatch stopwatch = Stopwatch.StartNew();
int sum = 0;
for (int i = 0; i < Iterations; i++)
{
if (func == null)
{
func = y => y + x;
}
sum += Apply(i, func);
}
stopwatch.Stop();
Console.WriteLine("Allocated in loop: {0}ms", stopwatch.ElapsedMilliseconds);
}
Таким образом, по-прежнему создается только один экземпляр делегата, но в цикле есть дополнительная логика - дополнительный тест на нулевое значение на каждой итерации,в основном.
На моей машине разница в производительности составляет около 15%.