使用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*)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
他们看起来和我完全一样.
原文地址:https://www.jb51.cc/csharp/100374.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。