Я пытался сравнить три разных способа передачи делегата функции в С# - с помощью lambda, делегатом и прямой ссылкой. Меня действительно удивил метод прямой ссылки (т.е. ComputeStringFunctionViaFunc(object[i].ToString))
был в шесть раз медленнее других методов. Кто-нибудь знает, почему это?
Полный код выглядит следующим образом:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
namespace FunctionInvocationTest
{
class Program
{
static void Main(string[] args)
{
object[] objectArray = new object[10000000];
for (int i = 0; i < objectArray.Length; ++i) { objectArray[i] = new object(); }
ComputeStringFunction(objectArray[0]);
ComputeStringFunctionViaFunc(objectArray[0].ToString);
ComputeStringFunctionViaFunc(delegate() { return objectArray[0].ToString(); });
ComputeStringFunctionViaFunc(() => objectArray[0].ToString());
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Start();
for (int i = 0; i < objectArray.Length; ++i)
{
ComputeStringFunction(objectArray[i]);
}
s.Stop();
Console.WriteLine(s.Elapsed.TotalMilliseconds);
s.Reset();
s.Start();
for (int i = 0; i < objectArray.Length; ++i)
{
ComputeStringFunctionViaFunc(delegate() { return objectArray[i].ToString(); });
}
s.Stop();
Console.WriteLine(s.Elapsed.TotalMilliseconds);
s.Reset();
s.Start();
for (int i = 0; i < objectArray.Length; ++i)
{
ComputeStringFunctionViaFunc(objectArray[i].ToString);
}
s.Stop();
Console.WriteLine(s.Elapsed.TotalMilliseconds);
s.Reset();
s.Start();
for (int i = 0; i < objectArray.Length; ++i)
{
ComputeStringFunctionViaFunc(() => objectArray[i].ToString());
}
s.Stop();
Console.WriteLine(s.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ComputeStringFunction(object stringFunction)
{
}
public static void ComputeStringFunctionViaFunc(Func<string> stringFunction)
{
}
}
}