Skip to content

Instantly share code, notes, and snippets.

@Mart-Bogdan
Last active July 13, 2023 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mart-Bogdan/86c4aef5d8463182fb739bffd32bca03 to your computer and use it in GitHub Desktop.
Save Mart-Bogdan/86c4aef5d8463182fb739bffd32bca03 to your computer and use it in GitHub Desktop.
Dotnet overhead of P/Invoke with ref arguments
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
namespace net_array_bench_app.Benches
{
// [SimpleJob(RuntimeMoniker.NetCoreApp31)]
// [SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[DisassemblyDiagnoser(maxDepth: 3)]
public class MarshalBench
{
[Benchmark()]
public unsafe void Fixed()
{
int x = 42;
fixed(int* p = MemoryMarshal.CreateSpan(ref x,1))
{
test_ref(p);
}
}
[Benchmark]
public void RefParameter()
{
int x = 42;
test_ref(ref x);
}
[SuppressGCTransition]
[DllImport("libarray_bench_rs.so", EntryPoint = "test_ref")]
unsafe static extern int test_ref(ref int x);
[SuppressGCTransition]
[DllImport("libarray_bench_rs.so", EntryPoint = "test_ref")]
unsafe static extern int test_ref(int* x);
}
}
BenchmarkDotNet=v0.13.5, OS=manjaro 
AMD Ryzen 7 5800H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.103
  [Host]   : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2
  .NET 7.0 : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2

Job=.NET 7.0  Runtime=.NET 7.0  
Method Mean Error StdDev Code Size
Fixed 1.089 ns 0.0202 ns 0.0169 ns 65 B
RefParameter 2.940 ns 0.0180 ns 0.0150 ns 33 B

.NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2

; net_array_bench_app.Benches.MarshalBench.Fixed()
       push      rbp
       sub       rsp,10
       lea       rbp,[rsp+10]
       mov       dword ptr [rbp-4],2A
       lea       rdi,[rbp-4]
       mov       [rbp-10],rdi
       mov       rax,7F488E76C230
       call      rax
       xor       eax,eax
       mov       [rbp-10],rax
       cmp       dword ptr [7F488E6A4930],0
       jne       short M00_L01
M00_L00:
       add       rsp,10
       pop       rbp
       ret
M00_L01:
       call      CORINFO_HELP_POLL_GC
       jmp       short M00_L00
; Total bytes of code 65

.NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2

; net_array_bench_app.Benches.MarshalBench.RefParameter()
       push      rbp
       sub       rsp,10
       lea       rbp,[rsp+10]
       mov       dword ptr [rbp-8],2A
       lea       rdi,[rbp-8]
       call      net_array_bench_app.Benches.MarshalBench.test_ref(Int32 ByRef)
       nop
       add       rsp,10
       pop       rbp
       ret
; Total bytes of code 33

PInvoke method net_array_bench_app.Benches.MarshalBench.test_ref(Int32 ByRef)

#[no_mangle]
pub extern "C" fn test_ref(x:*mut i32){}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment