在 dotnet 里面,拿到一個指標,可以有多個不同的方法轉換為結構體,本文將來告訴大家這幾個方法的性能的差別
特別感謝性能優化狂魔 Stephen Toub 大佬的指導
在 WPF 框架開發中,有小伙伴 ThomasGoulet73 問 Stephen Toub 大佬關于從指標轉換為結構體的性能差別,請看 https://github.com/dotnet/wpf/pull/4917#discussion_r690587610
此時 Stephen Toub 大佬給出的性能測驗如下

通過 Cast 轉換的性能是最佳的,但是需要用上不安全代碼,使用的時候也有很多注意的事項,而采用 Marshal 的 PtrToStructure 有兩個多載的方法,一個是泛型的,一個是非泛型的,測驗代碼如下
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Runtime.InteropServices;
[MemoryDiagnoser]
public class Program
{
public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
private IntPtr _ptr;
[GlobalSetup]
public unsafe void Setup() => _ptr = Marshal.AllocHGlobal(sizeof(MyPoint));
[GlobalCleanup]
public void Cleanup() => Marshal.FreeHGlobal(_ptr);
[Benchmark]
public unsafe MyPoint Cast() => *(MyPoint*)_ptr; // 0.0477ns
[Benchmark]
public MyPoint PtrToStructureGeneric() => Marshal.PtrToStructure<mypoint>(_ptr); // 26.2864ns
[Benchmark]
public MyPoint PtrToStructureNonGeneric() => (MyPoint)Marshal.PtrToStructure(_ptr, typeof(MyPoint)); // 28.2225ns
}
[StructLayout(LayoutKind.Sequential)]
public struct MyPoint
{
public int X;
public int Y;
}
在 Stephen Toub 大佬的建議是,雖然 Cast 方法,通過不安全代碼指標轉換的方法的性能足夠好,如上面測驗 只需 0.0477 納秒,但是只有在型別是 blittable(可直接復制到本機結構中的型別)的時候才適合用強轉的方式,否則還是需要使用 Marshal 的方法處理封送
博客園博客只做備份,博客發布就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可,歡迎轉載、使用、重新發布,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布,如有任何疑問,請與我[聯系](mailto:[email protected]),
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/295838.html
標籤:WPF
上一篇:六、從GitHub瀏覽Prism示例代碼的方式入門WPF下的Prism之MVVM中的FilteringEvents
