SUMTEC -- There's a thing in my bloglet.

But it's not only one. It's many. It's the same as other things but it exactly likes nothing else...

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
昨天研究一个delegate的问题,研究了半天,找出了很多的东西来。但是就是有一点始终搞不清楚:为什么某个事件添加一次和添加两次,时间上会相差四倍呢?开始我觉得是递归调用的错,dudu说是运行时生成的问题。实际上现在我做的试验表明很可能大家都错了:

首先我们尝试一下1->2,我们会发现接口的时间增加成比例关系,也就是1->2,可是事件花费的时间则是1->4。这个就是我们觉得非常奇怪的地方,为什么会超出线形关系呢?我开始认为是递归调用的结果,后来发现不是这么回事,因为我做了一个模仿delegate/multicastdelegate的类(除了不是delegate之外,行为几乎一样),然后进行模拟。发现递归和循环之间的差别并不是很明显,基本上相差30%左右。但是同时你也能够发现,无论添加的事件是多少个,递归和循环一样,消耗的时间都保持着线形的关系。

看到这里我们非常的奇怪,既然不是递归的问题,那么难道是运行时产生代码的问题?那也不可能啊,因为那也应该保持着线形的关系啊。

好,现在我们继续做试验:如果我们继续添加事件,比如2->3,那么我们看到interface那边消耗的时间也是2->3,event呢,则是4->6。再比如3->4,interface消耗时间变化是3->4,event则是6->8。
好了,原因几乎就是一目了然了:event的问题仅仅出在1->2,其他地方实际上还是线形关系的。那么在1->2的时候到底发生了什么事情呢?联想一件事情,在昨天的几篇文章中的一篇提到:“由于是runtime的,所以executor会进行优化,但是这个特性并没有在现在的编译器里面很好的实现,只是未来的特性。同时我也不认为这个特性会被添加到1.1版本的运行库里面。”(大意如此)

所以我现在有理由假设一件事情:那就是如果一个委托只被分派了一次,那么这个委托的基类就是Delegate,或者用一个简化的函数实现Invoke。反之,如果这个委托被分派了多次,那么这个委托的基类就是MultiCaseDelegate,或者用一个比较复杂的函数实现Invoke。这就造成了1->2之间的超线性关系,而2->3、3->4则保持了线性关系的原因——仅仅是猜测。

由于目前也仅仅是一个猜测,我想还是需要更多的试验来证实这个想法。不过我最近可能要忙着做别的事情了,所以这个试验就留给各位来试验了。

注:这里面提到的“时间添加两次”的意思大概就是:
t.Event += new xxHandler(xx1);
t.Event += new xxHandler(xx2);
而不是:
t.Event1 += new xxHandler(xx1);
t.Event2 += new xxHandler(xx2);
posted on 2004-05-24 10:05  Sumtec  阅读(1211)  评论(3编辑  收藏  举报