C# 方法转为委托类型时时具体做了什么
之前发现了一个很有意思的事,如果将方法作为委托参数传递给另一个方,循环N次执行这个操作,好像方法隐式转换成委托时,会有额外的性能消耗,相比直接弄一个匿名委托,要慢很多,代码如下
static void Start() {
for (int i = 0; i < 5; i++) {
CompareSpeed(AAA);
CompareSpeed(BBB);
CompareSpeed(AAA);
Console.WriteLine("===========");
}
}
readonly static int len = 1024 * 1024;
static void CompareSpeed(Action action) {
Stopwatch sw = new Stopwatch();
sw.Start();
action();
Console.WriteLine(action.Method.Name + ":" + sw.ElapsedTicks);
}
static void AAA() {
for (int i = 0; i < len; i++) {
Test(DoSomething);
}
}
static void BBB() {
for (int i = 0; i < len; i++) {
Test(() => {
int a = 1;
});
}
}
static void Test(Action action) {
action();
}
static void DoSomething() {
int a = 1;
}
结果如下:
AAA:327427
BBB:119771
AAA:302877
AAA:191837
BBB:93651
AAA:200357
AAA:347466
BBB:292075
AAA:234907
AAA:207438
BBB:94038
AAA:189342
AAA:208228
BBB:99733
AAA:187513
在1M的循环次数下,明显可以看到AAA普遍慢于BBB
BBB我理解的是因为里面的匿名函数只创建一次,之后在循环时,都是直接拿已经创建好的
那么AAA慢是不是因为每次都要执行方法隐式转成Action啊,这个隐式转成具体是做了什么啊,我知道委托怎么用,但是不知道委托内部是怎么实现的,网上也收不到相关的内容,有大佬能详细的讲讲吗
而且我发现,如果将循环次数减少,就没有这么明显了,基本都是刚开始的几次AAA比BBB快,次数上来后才体现出BBB比AAA快,这么看的话,是不是AAA的隐式转换要比新创建一个匿名函数要快很多啊,() => { int a = 1; }按我的理解是匿名函数,它和普通的方法有什么区别啊,它可以直接赋值给Action,它的类型是委托吗,还是说它依然是个方法,依然是隐式转换成Action的啊
回答
Test(DoSomething); ==> Test(new Action(DoSomething))
Test(() => {int a = 1;});
==>
static 自动生成的静态类 {static action=new Action(()=>int a=1;)}
Test(自动生成的静态类.action) // 直接引用传递.
//会编译成一个静态类包含这个静态Action方法.
所以AAA方法的多出来的消耗在每次循环的new Action上.