dotnet 對指針轉換為結構體多個不同方法的性能分析


在 dotnet 里面,拿到一個指針,可以有多個不同的方法轉換為結構體,本文將來告訴大家這幾個方法的性能的差別

特別感謝性能優化狂魔 Stephen Toub 大佬的指導

在 WPF 框架開發中,有小伙伴 ThomasGoulet73Stephen 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 的方法處理封送


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM