Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
.NET CLR provides great managed memory management. But there are occasions when we want to manage memory on our own. And yes, CLR allows a C# program to call native code via P/Invoke. There is nothing wrong with P/Invoke until we need to call a native API many times in a performance critical code section. Graph Engine provides a set of lightweight wrappers for the commonly-used C memory management functions, such as malloc, free, memcpy, memmove, and memcmp.
To use these functions, create a “Graph Engine Application Project” in Visual Studio and add the namespace “Trinity.Core.Lib”. Compared with their P/Invoked counterparts, the Graph Engine wrappers can usually give us a little bit performance edge. Try out the following code snippet:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Trinity;
using Trinity.Core.Lib;
namespace GraphEngineApp1
{
unsafe internal class Program
{
static void Main(string[] args)
{
int count = 1000000;
void* src = Memory.malloc(300);
void* dst = Memory.malloc(300);
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
Memory.memcpy(dst, src, 300);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Memory.free(src);
Memory.free(dst);
}
}
}
Now replace the “Memory.memcpy(dst, src, 300) ” with the P/Invoked version, and run again. On my machine, the GE wrapper version takes 14 ms, while the P/Invoked version takes 25 ms.
Use P/Invoke if its overhead is negligible for your application. Consider giving the GE wrappers a shot if the overhead caused by P/Invoke starts to bother you.