c# – ldobj和ldind有什么区别,为什么ldobj会更快?
发布时间:2020-12-15 08:01:48 所属栏目:百科 来源:网络整理
导读:使用64位大小的结构时,请使用以下代码段 [StructLayout(LayoutKind.Explicit,Pack = 1,Size = 8)] unsafe struct BUF { }((BUF*)dst) = *((BUF*)src); 产生 IL_0046: nop IL_0047: ldloc.s dst IL_0049: ldloc.2 IL_004a: ldobj MyClass/BUF IL_004f: stobj
使用64位大小的结构时,请使用以下代码段
[StructLayout(LayoutKind.Explicit,Pack = 1,Size = 8)] unsafe struct BUF { } ((BUF*)dst) = *((BUF*)src); 产生 IL_0046: nop IL_0047: ldloc.s dst IL_0049: ldloc.2 IL_004a: ldobj MyClass/BUF IL_004f: stobj MyClass/BUF 但是,当只使用long时,会生成以下代码 *((long*)dst) = *((long*)src); 生产: IL_0046: nop IL_0047: ldloc.s dst IL_0049: ldloc.2 IL_004a: ldind.i8 IL_004b: stind.i8 有没有人知道ldobj / stobj和ldind.i8 / stind.i8对于这个例子有什么区别? ldobj / stobj似乎提高了20%的性能,但我无法弄清楚为什么会这样.这两条线是不是完全一样? 谢谢! 编辑:[64位释放模式]在发布模式下编译时,字节码看起来相同.性能测量不久前在发布模式下完成. 解决方法
我已经复制了你正在使用的两种不同的方法,并且看到生成了相同的IL,但是当在Release模式下运行时,两者的jitted代码完全相同:
这是我使用的测试方法: using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Test { [StructLayout(LayoutKind.Explicit,Size = 8)] unsafe struct BUF { } static class Program { static void Main() { BUF x,y,z; unsafe { Do1(&x,&y); Do2(&y,&z); } // Readline here to allow attaching debugger and dumping jitted code Console.ReadLine(); } // Disable inlining to permit easier identification of the code [MethodImpl(MethodImplOptions.NoInlining)] unsafe static void Do1(BUF* src,BUF* dst) { *((BUF*)dst) = *((BUF*)src); } // Disable inlining to permit easier identification of the code [MethodImpl(MethodImplOptions.NoInlining)] unsafe static void Do2(BUF* src,BUF* dst) { *((long*)dst) = *((long*)src); } } } 这两种方法的IL与您的匹配: DO1: IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: ldobj Test.BUF IL_0007: stobj Test.BUF IL_000c: ret DO2: IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: ldind.i8 IL_0003: stind.i8 IL_0004: ret 并转储jitted代码: DO1: Test.Program.Do1(Test.BUF*,Test.BUF*) Begin 000007ff00170190,size 7 000007ff`00170190 488b01 mov rax,qword ptr [rcx] 000007ff`00170193 488902 mov qword ptr [rdx],rax 000007ff`00170196 c3 ret DO2: Test.Program.Do2(Test.BUF*,Test.BUF*) Begin 000007ff001701b0,size 7 000007ff`001701b0 488b01 mov rax,qword ptr [rcx] 000007ff`001701b3 488902 mov qword ptr [rdx],rax 000007ff`001701b6 c3 ret 他们看起来和我完全一样. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |