内容简介:代码日志版权声明:翻译自:http://stackoverflow.com/questions/32071087/weird-performance-behavior
所以我有这2个方法,假设将1000个长整数的整数乘以2.
第一种方法:
[MethodImpl(MethodImplOptions.NoOptimization)] Power(int[] arr) { for (int i = 0; i < arr.Length; i++) { arr[i] = arr[i] + arr[i]; } }
第二种方法:
[MethodImpl(MethodImplOptions.NoOptimization)] PowerNoLoop(int[] arr) { int i = 0; arr[i] = arr[i] + arr[i]; i++; arr[i] = arr[i] + arr[i]; i++; arr[i] = arr[i] + arr[i]; i++; ............1000 Times........ arr[i] = arr[i] + arr[i]; }
请注意,我将此代码仅用于性能研究,这就是为什么它看起来很恶心.
令人吃惊的结果是,Power已经比PowerNoLoop快了近50%,即使我检查了它们的反编译的IL源,并且For循环的内容与PowerNoLoop中的每一行完全相同.
怎么会这样?
从我的机器的一个样品测量,运行测试10次,PowerNoLoop是第一:
00:00:00.0277138 00:00:00.0001553 00:00:00.0000142 00:00:00.0000057 00:00:00.0000106 00:00:00.0000053 00:00:00.0000084 00:00:00.0000053 00:00:00.0000080 00:00:00.0000053 00:00:00.0000075 00:00:00.0000053 00:00:00.0000080 00:00:00.0000057 00:00:00.0000080 00:00:00.0000053 00:00:00.0000080 00:00:00.0000053 00:00:00.0000075 00:00:00.0000053
是的,慢50%左右值得注意的是,首次通过测试时的抖动开销,显然它会燃烧更多的核心,试图得到这个巨大的方法编译.请记住,当您不禁用优化器时,测量值会大不相同,所以无循环版本的速度会慢一些〜800%.
首先总是寻找一个解释是生成的机器代码,你可以看到它与Debug> Windows>拆卸.主要的麻烦是PowerNoLoop()方法的序幕.在x86代码中看起来像这样:
067E0048 push ebp ; setup stack frame 067E0049 mov ebp,esp 067E004B push edi ; preserve registers 067E004C push esi 067E004D sub esp,0FA8h ; stack frame size = 4008 bytes 067E0053 mov esi,ecx 067E0055 lea edi,[ebp-0ACCh] ; temp2 variables 067E005B mov ecx,2B1h ; initialize 2756 bytes 067E0060 xor eax,eax ; set them to 0 067E0062 rep stos dword ptr es:[edi]
注意非常大的堆栈大小,4008字节.对于只有一个局部变量的方法来说太多了,它只需要8个字节.额外的4000个是临时变量,我把它命名为temp2.它们由代码指令初始化为0,这需要一段时间.我不能解释2756.
个人补充是非优化代码中非常漂亮的事情.我将为您提供机器代码转储,并将其写入等效的C#代码:
if (i >= arr.Length) goto throwOutOfBoundsException var temp1 = arr[i]; if (i >= arr.Length) goto throwOutOfBoundsException var temp2 = temp1 + arr[i]; if (i >= arr.Length) goto throwOutOfBoundsException arr[i] = temp2
一遍又一遍地重复,总共一千次. temp2变量是麻烦制造者,每个单独的语句有一个.因此,为堆栈帧大小添加4000字节.如果有人猜到2756,那么我很乐意在评论中听到.
在方法开始运行之前,必须将它们全部设置为0,大概是什么导致50%的减速.也可能有一些指令提取和解码开销,它不能从测量中轻松隔离.
值得注意的是,当您删除[MethodImpl]属性并允许优化器执行其作业时,它们不会被消除.实际上,该方法根本没有优化,因为它不想解决这么大的代码块.
总结你应该画的是永远保持抖动优化器为你展开循环.它知道得更好
代码日志版权声明:
翻译自:http://stackoverflow.com/questions/32071087/weird-performance-behavior
以上所述就是小编给大家介绍的《c# – 奇怪的表现行为》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTTP Essentials
Stephen A. Thomas、Stephen Thomas / Wiley / 2001-03-08 / USD 34.99
The first complete reference guide to the essential Web protocol As applications and services converge and Web technologies not only assume HTTP but require developers to manipulate it, it is be......一起来看看 《HTTP Essentials》 这本书的介绍吧!