2021-07-01

dotnet C# 调用委托的 GetInvocationList 的对象分配

本文也叫跟着 Stephen Toub 大佬学性能优化系列,这是我从 Stephen Toub 大佬给 WPF 框架做性能优化学到的知识,在热路径下,也就是频繁调用的模块,如果调用了委托的 GetInvocationList 方法,那么将视委托的大小,每次创建不同大小的新数组对象,而在频繁调用的模块,将会创建大量的对象

本文也叫跟着 Stephen Toub 大佬学性能优化系列,这是我从 Stephen Toub 大佬给 WPF 框架做性能优化学到的知识,在热路径下,也就是频繁调用的模块,如果调用了委托的 GetInvocationList 方法,那么将视委托的大小,每次创建不同大小的新数组对象,而在频繁调用的模块,将会创建大量的对象

如以下代码的一个委托,当然对于事件来说也是如此

   Action action = Foo;   for (int i = 0; i < 10; i++)   {    action += Foo;   }   static void Foo()   {   }

如果调用了 action 的 GetInvocationList 方法,那么在每次调用都会申请一些内存,如使用以下代码进行测试

   for (int i = 0; i < 100; i++)   {    var beforeAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();    var invocationList = action.GetInvocationList();    var afterAllocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread();    Console.WriteLine(afterAllocatedBytesForCurrentThread - beforeAllocatedBytesForCurrentThread);   }

上面代码的 GetAllocatedBytesForCurrentThread 是一个放在 GC 层面的方法,可以用来获取当前线程分配过的内存大小,这是一个用来辅助调试的方法。详细请看 dotnet 使用 GC.GetAllocatedBytesForCurrentThread 获取当前线程分配过的内存大小

可以看到运行时的控制台输出如下

312112112112112112112112112112112112// 不水了

这是因为在底层的实现,调用 GetInvocationList 方法的代码如下

 public override sealed Delegate[] GetInvocationList() {  Delegate[] delegateArray;  if (!(this._invocationList is object[] invocationList))  {  delegateArray = new Delegate[1]{ (Delegate) this };  }  else  {  delegateArray = new Delegate[(int) this._invocationCount];  for (int index = 0; index < delegateArray.Length; ++index)   delegateArray[index] = (Delegate) invocationList[index];  }  return delegateArray; }

可以看到每次都需要重新申请数组,然后给定数组里面的元素。如果在调用频繁的模块里面,不断调用 GetInvocationList 方法,将会有一定的性能损耗。如在 WPF 的移动鼠标等逻辑里面

一个优化的方法是,如果指定的委托或事件的加等次数比调用 GetInvocationList 的次数少,如 WPF 的 PreNotifyInput 等事件,此时可以通过在加等的时候缓存起来,这样后续的调用就不需要重新分配......

原文转载:http://www.shaoqun.com/a/839213.html

跨境电商:https://www.ikjzd.com/

csa认证:https://www.ikjzd.com/w/904

crowd:https://www.ikjzd.com/w/880

雨果网:https://www.ikjzd.com/w/1307


本文也叫跟着StephenToub大佬学性能优化系列,这是我从StephenToub大佬给WPF框架做性能优化学到的知识,在热路径下,也就是频繁调用的模块,如果调用了委托的GetInvocationList方法,那么将视委托的大小,每次创建不同大小的新数组对象,而在频繁调用的模块,将会创建大量的对象本文也叫跟着StephenToub大佬学性能优化系列,这是我从StephenToub大佬给WPF框架
2019亚马逊Q4即将来临,卖家要做好这些准备!:https://www.ikjzd.com/articles/106949
旺季Wish小卖家如何强势逆袭,瓜分平台流量?:https://www.ikjzd.com/articles/106950
网易考拉PC端和APP均正式更名"考拉海购"!:https://www.ikjzd.com/articles/106951
外媒如何评论?中美贸易战对美国经济有何影响?:https://www.ikjzd.com/articles/106952
解开扣子两只大白兔 一口咬住胸前两颗葡萄:http://lady.shaoqun.com/a/247394.html
我接的黑人客人好痛苦 黑人锁住高潮也不拔出来:http://lady.shaoqun.com/a/247110.html
口述:妹妹和我男友爱爱时故意呻吟口述爱爱妹妹:http://lady.shaoqun.com/a/25015.html
囗述我互换丈夫过程 邻居大棒在我体内不停抽搐:http://lady.shaoqun.com/m/a/246753.html
亚马逊商家只会卖货不赚钱:https://www.ikjzd.com/articles/146274
520、睡前三个超级甜的故事哄女朋友:http://lady.shaoqun.com/a/394662.html
不要轻举妄动:一时冲动会发生男女性交:http://lady.shaoqun.com/a/394663.html
WISH宣布重新开放旧金山总部,提供灵活的工作选择:https://www.ikjzd.com/articles/146288

No comments:

Post a Comment