From ca5a5b4d164747b83cb73332b8a8df545b024121 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Thu, 5 Dec 2013 11:20:58 +0100 Subject: [PATCH] Reduce temporary string allocations Instead of modifying the name of an OpenGL symbol on the managed side, before copying it to the unmanaged side, we perform the modification directly on the unmanaged side. This reduces the total amount of allocations in OpenTK by ~30% (673496 bytes in 10750 objects compared to 930272 bytes in 15243 objects before this modification.) --- Source/OpenTK/Platform/MacOS/AglContext.cs | 38 +++++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index 867c5dc0..65bdd0af 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -479,15 +479,35 @@ namespace OpenTK.Platform.MacOS public override IntPtr GetAddress(string function) { - string fname = "_" + function; - if (!NSIsSymbolNameDefined(fname)) - return IntPtr.Zero; - - IntPtr symbol = NSLookupAndBindSymbol(fname); - if (symbol != IntPtr.Zero) - symbol = NSAddressOfSymbol(symbol); - - return symbol; + // Instead of allocating and combining strings in managed memory + // we do that directly in unmanaged memory. This way, we avoid + // 2 string allocations every time this function is called. + + // must add a '_' prefix and null-terminate the function name, + // hence we allocate +2 bytes + IntPtr ptr = Marshal.AllocHGlobal(function.Length + 2); + try + { + Marshal.WriteByte(ptr, (byte)'_'); + for (int i = 0; i < function.Length; i++) + { + Marshal.WriteByte(ptr, i + 1, (byte)function[i]); + } + Marshal.WriteByte(ptr, function.Length + 1, 0); // null-terminate + + IntPtr symbol = IntPtr.Zero; + if (NSIsSymbolNameDefined(ptr)) + { + symbol = NSLookupAndBindSymbol(ptr); + if (symbol != IntPtr.Zero) + symbol = NSAddressOfSymbol(symbol); + } + return symbol; + } + finally + { + Marshal.FreeHGlobal(ptr); + } } public override IntPtr GetAddress(IntPtr function)