内容简介:代码日志版权声明:翻译自: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# – 奇怪的表现行为》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript DOM编程艺术 (第2版)
[英] Jeremy Keith、[加] Jeffrey Sambells / 杨涛、王建桥、杨晓云 等 / 人民邮电出版社 / 2011-4 / 49.00元
JavaScript是Web开发中最重要的一门语言,它强大而优美。无论是桌面开发,还是移动应用。JavaScript都是必须掌握的技术。W3C的DOM标准是开发Web应用的基石。已经得到所有现代浏览器的支持,这使得跨平台Web开发成了一件轻松惬意的事。 本书是超级畅销书的升级版,由倡导Web标准的领军人物执笔,揭示了前端开发的真谛,是学习JavaScript和DOM开发的必读之作。 本......一起来看看 《JavaScript DOM编程艺术 (第2版)》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
Markdown 在线编辑器
Markdown 在线编辑器