首页 > 代码库 > 通过编译的方式,思考如何让程序更快(原创)
通过编译的方式,思考如何让程序更快(原创)
在.NET程序第一阶段编译时,有两种方式:
Debug版本主要便于调试分析。
Release版本进行了各种优化,体积更小、执行更快、编译更慢更严格。
体积更小,主要是因为Release版本中去掉了程序中所有的断点、代码行等调试信息。
那么执行更快究竟为什么呢?
一段简单的测试代码(原创帖,转载请说明出处)
用WinDbg分析Debug版本
1 Normal JIT generated code 2 ConsoleApp.Program.Main() 3 Begin 000007fe94260090, size 48 4 *** WARNING: Unable to verify checksum for ConsoleApp.exe 5 6 D:\Study\ConsoleApp\Program.cs @ 19: 7 >>> 000007fe`94260090 4883ec28 sub rsp,28h 8 000007fe`94260094 48b848341494fe070000 mov rax,7FE94143448h 9 000007fe`9426009e 8b00 mov eax,dword ptr [rax]10 000007fe`942600a0 85c0 test eax,eax11 000007fe`942600a2 7405 je 000007fe`942600a912 000007fe`942600a4 e85363a45f call clr!JIT_DbgIsJustMyCode (000007fe`f3ca63fc)13 000007fe`942600a9 90 nop14 15 D:\Study\ConsoleApp\Program.cs @ 20:16 000007fe`942600aa b901000000 mov ecx,117 000007fe`942600af e874bfeeff call 000007fe`9414c028 (ConsoleApp.Program.Add(Int32), mdToken: 0000000006000002)18 000007fe`942600b4 90 nop19 20 D:\Study\ConsoleApp\Program.cs @ 21:21 000007fe`942600b5 66ba2b00 mov dx,2Bh22 000007fe`942600b9 b901000000 mov ecx,123 000007fe`942600be e86dbfeeff call 000007fe`9414c030 (ConsoleApp.Program.Calc(Int32, Char), mdToken: 0000000006000003)24 000007fe`942600c3 90 nop25 26 D:\Study\ConsoleApp\Program.cs @ 22:27 000007fe`942600c4 8b0d7a35eeff mov ecx,dword ptr [000007fe`94143644]28 *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_64\mscorlib\abf62e6545d2802fc60286678a67e6bf\mscorlib.ni.dll29 000007fe`942600ca e8b1d2d256 call mscorlib_ni+0xd0d380 (000007fe`eaf8d380) (System.Console.WriteLine(Int32), mdToken: 0000000006000990)30 000007fe`942600cf 90 nop31 32 D:\Study\ConsoleApp\Program.cs @ 23:33 000007fe`942600d0 eb00 jmp 000007fe`942600d234 000007fe`942600d2 90 nop35 000007fe`942600d3 4883c428 add rsp,28h36 000007fe`942600d7 c3 ret
用WinDbg分析Release版本
1 Normal JIT generated code 2 ConsoleApp.Program.Main() 3 Begin 000007fe94260090, size 29 4 *** WARNING: Unable to verify checksum for ConsoleApp.exe 5 6 D:\Study\ConsoleApp\Program.cs @ 20: 7 >>> 000007fe`94260090 4883ec28 sub rsp,28h 8 000007fe`94260094 ff05aa35eeff inc dword ptr [000007fe`94143644] 9 10 D:\Study\ConsoleApp\Program.cs @ 21:11 000007fe`9426009a 66ba2b00 mov dx,2Bh12 000007fe`9426009e b901000000 mov ecx,113 000007fe`942600a3 e888bfeeff call 000007fe`9414c030 (ConsoleApp.Program.Calc(Int32, Char), mdToken: 0000000006000003)14 15 D:\Study\ConsoleApp\Program.cs @ 22:16 000007fe`942600a8 8b0d9635eeff mov ecx,dword ptr [000007fe`94143644]17 *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_64\mscorlib\abf62e6545d2802fc60286678a67e6bf\mscorlib.ni.dll18 000007fe`942600ae e8cdd2d256 call mscorlib_ni+0xd0d380 (000007fe`eaf8d380) (System.Console.WriteLine(Int32), mdToken: 0000000006000990)19 000007fe`942600b3 90 nop20 000007fe`942600b4 4883c428 add rsp,28h21 000007fe`942600b8 c3 ret
可以看出:
大小:Debug版本size 48,Release版本size 29
19行:Debug版本有进入Main方法的代码块的额外操作(待研究)
20行:Debug版本有调用Add方法的开销,Release版本内联处理而直接inc计算
21行:由于Calc方法包含异常处理模块,所以无法内联,Debug版本和Release版本都有调用的开销
22行:都有调用系统方法WriteLine的开销
23行:Debug版本有离开Main方法的代码块的额外操作
实际上,JIT使用大量的探测方法来确定是否应内联某个方法,虽然不必刻意使所写的方法满足内联的条件,但合理使用有助于让程序更快。
通过编译的方式,思考如何让程序更快(原创)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。