Summary
The current C# wrapper around the native interface relies heavily on IntPtr usage, which introduces unnecessary overhead in performance‑critical paths. This affects both call latency and memory churn, especially when repeatedly converting pointers, allocating unmanaged memory, or performing redundant marshaling.
Problem Details
- Frequent
IntPtr → delegate conversions using Marshal.GetDelegateForFunctionPointer
- Repeated calls into native code instead of batching operations
- Use of non‑blittable structs causing marshaling overhead
- Unnecessary allocations via
Marshal.AllocHGlobal and Marshal.Copy
- Delegates used where function pointers (
delegate* unmanaged) would be faster
- Potential boxing of
IntPtr values in wrapper classes or collections
SafeHandle usage in hot paths adding reference counting and finalization overhead
Proposed Improvements
- Cache all function pointers at initialization time
- Replace delegates with
delegate* unmanaged where possible
- Ensure structs passed to native code are blittable
- Pin managed buffers instead of allocating unmanaged memory
- Reduce managed↔native transitions by batching operations
- Avoid
SafeHandle in performance‑critical paths when lifetime is already controlled
- Use
[NativeLibrary.Load](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary.load?view=net-9.0) and NativeLibrary.GetExport for explicit control over symbol resolution
Expected Benefits
- Lower call overhead for native function invocations
- Reduced GC pressure from fewer allocations
- Faster throughput in tight loops or high‑frequency native calls
- More predictable performance characteristics
Summary
The current C# wrapper around the native interface relies heavily on
IntPtrusage, which introduces unnecessary overhead in performance‑critical paths. This affects both call latency and memory churn, especially when repeatedly converting pointers, allocating unmanaged memory, or performing redundant marshaling.Problem Details
IntPtr→ delegate conversions usingMarshal.GetDelegateForFunctionPointerMarshal.AllocHGlobalandMarshal.Copydelegate* unmanaged) would be fasterIntPtrvalues in wrapper classes or collectionsSafeHandleusage in hot paths adding reference counting and finalization overheadProposed Improvements
delegate* unmanagedwhere possibleSafeHandlein performance‑critical paths when lifetime is already controlled[NativeLibrary.Load](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary.load?view=net-9.0)andNativeLibrary.GetExportfor explicit control over symbol resolutionExpected Benefits