diff --git a/.github/workflows/nng.yml b/.github/workflows/nng.yml index 3bc76b1..8b70324 100644 --- a/.github/workflows/nng.yml +++ b/.github/workflows/nng.yml @@ -30,7 +30,7 @@ jobs: uses: actions/upload-artifact@v2 with: path: | - nng.NETCore/runtimes/**/* - !nng.NETCore/runtimes/any/**/* + nng.NET/runtimes/**/* + !nng.NET/runtimes/any/**/* if-no-files-found: error diff --git a/benchmarks/Benchmarks.cs b/benchmarks/Benchmarks.cs new file mode 100644 index 0000000..cf87c43 --- /dev/null +++ b/benchmarks/Benchmarks.cs @@ -0,0 +1,105 @@ +using BenchmarkDotNet; +using BenchmarkDotNet.Attributes; +using nng; +using nng.Native; +using System; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace benchmarks +{ + public class Delegate + { + delegate int nng_aio_set_output_delegate(nng_aio aio, int index, IntPtr arg); + nng_aio_set_output_delegate nng_aio_set_output; + + [GlobalSetup] + public void GlobalSetup() + { + var handle = DllImport.Load(); + var ptr = NativeLibrary.GetExport(handle, "nng_aio_set_output"); + nng_aio_set_output = Marshal.GetDelegateForFunctionPointer(ptr); + } + + [Benchmark] + public void CallDelegate() + { + var _ = nng_aio_set_output(nng_aio.Null, 9, IntPtr.Zero); + } + } + + public unsafe class Pointer + { + delegate* unmanaged[Cdecl] nng_aio_set_output; + + [GlobalSetup] + public void GlobalSetup() + { + var handle = DllImport.Load(); + + var ptr = NativeLibrary.GetExport(handle, "nng_aio_set_output"); + nng_aio_set_output = (delegate* unmanaged[Cdecl])ptr; + } + + [Benchmark] + public void CallFunctionPointer() + { + var _ = nng_aio_set_output(IntPtr.Zero, 9, IntPtr.Zero); + } + } + + public class DllImport + { + [GlobalSetup] + public void GlobalSetup() + { + //System.Console.WriteLine("GlobalSetup: " + System.IO.Directory.GetCurrentDirectory()); + NativeLibrary.SetDllImportResolver(typeof(nng.Native.Basic.UnsafeNativeMethods).Assembly, DllImportResolver); + } + + [Benchmark] + public void CallDllImport() + { + var _ = nng.Native.Aio.UnsafeNativeMethods.nng_aio_set_output(nng_aio.Null, 9, IntPtr.Zero); + } + + [Benchmark(Baseline = true)] + public void CallManaged() + { + var _ = Managed(IntPtr.Zero, 9, IntPtr.Zero); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static nint Managed(nint _unused0, int _unused1, nint _unused2) => 0; + + static IntPtr DllImportResolver(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath) + { + return Load(); + } + + public static IntPtr Load() + { + return NativeLibrary.Load("/Users/j_woltersdorf/projects/nng.NETCore/nng.NET/runtimes/osx-x64/native/libnng.dylib"); + } + } + + public class Interface + { + IAPIFactory Factory { get; set; } + + [GlobalSetup] + public void GlobalSetup() + { + var alc = new NngLoadContext("/Users/j_woltersdorf/projects/nng.NETCore/nng.NET/"); + Factory = NngLoadContext.Init(alc); + } + + [Benchmark] + public void CallInterfaceToDllImport() + { + Factory.CreateAlloc(0); + System.Threading.Thread.Sleep(1); + } + } +} diff --git a/benchmarks/Program.cs b/benchmarks/Program.cs new file mode 100644 index 0000000..3fd5e1c --- /dev/null +++ b/benchmarks/Program.cs @@ -0,0 +1,17 @@ +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Running; + +namespace benchmarks +{ + class Program + { + static void Main(string[] args) + { + System.Console.WriteLine(System.IO.Directory.GetCurrentDirectory()); + var config = ManualConfig.Create(DefaultConfig.Instance) + .WithOptions(ConfigOptions.JoinSummary) + .AddExporter(BenchmarkDotNet.Exporters.Json.JsonExporter.Full); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); + } + } +} \ No newline at end of file diff --git a/benchmarks/benchmarks.csproj b/benchmarks/benchmarks.csproj new file mode 100644 index 0000000..87399be --- /dev/null +++ b/benchmarks/benchmarks.csproj @@ -0,0 +1,22 @@ + + + net5.0 + Exe + + + AnyCPU + portable + true + true + true + Release + + + + + + + + + + \ No newline at end of file diff --git a/clangsharp.rsp b/clangsharp.rsp new file mode 100644 index 0000000..f8f2c69 --- /dev/null +++ b/clangsharp.rsp @@ -0,0 +1,6 @@ +--file +nng/include/nng/nng.h +--namespace +nng +--output +./interop diff --git a/dockerfiles/build_nng/Dockerfile b/dockerfiles/build_nng/Dockerfile index 76b4263..d3a645b 100644 --- a/dockerfiles/build_nng/Dockerfile +++ b/dockerfiles/build_nng/Dockerfile @@ -19,9 +19,9 @@ ARG SRC ARG NNG_BRANCH=v1.4.0 WORKDIR ${SRC} -RUN git clone https://github.com/nanomsg/nng.git \ - && cd nng \ - && git checkout ${NNG_BRANCH} +RUN git clone \ + -b ${NNG_BRANCH} --depth 1 --recursive --single-branch \ + https://github.com/nanomsg/nng.git # Build x64 Linux FROM debian:buster AS linux-x64 diff --git a/scripts/build_nng.ps1 b/scripts/build_nng.ps1 index 3ac60d4..74c9884 100755 --- a/scripts/build_nng.ps1 +++ b/scripts/build_nng.ps1 @@ -5,7 +5,7 @@ param([string]$nng_source = "../nng/", [switch]$clean, [string]$git_branch, -[string]$runtimes = "$PSScriptRoot/../nng.NETCore/runtimes" +[string]$runtimes = "$PSScriptRoot/../nng.NET/runtimes" ) if (-not $IsLinux -and -not $(Test-Path $nng_source -PathType Container)){ @@ -33,7 +33,7 @@ try { if ($IsLinux) { docker build -t jeikabu/build-nng dockerfiles/build_nng docker run --rm --privileged multiarch/qemu-user-static:register - docker run -i -t --rm -v "$PWD/nng.NETCore/runtimes:/runtimes" jeikabu/build-nng + docker run -i -t --rm -v "$PWD/nng.NET/runtimes:/runtimes" jeikabu/build-nng } else { Write-Host "Placing nng $platforms binaries in $runtimes..."