C#内存复制性能分析
static class Program { [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { LogStopwatch stopwatch = new LogStopwatch("内存操作"); int size = 1024 * 1024 * 1024; byte[] data1 = new byte[size]; byte[] data2 = new byte[size]; stopwatch.Peek("分配"); for(int l = 0; l < size; l++) { data1[l] = (byte)(l & 0xFF); } stopwatch.Peek("赋值"); Array.Copy(data1, data2, data1.Length); stopwatch.Peek("Array.Copy: byte[] -> byte[]"); Array.ConstrainedCopy(data1, 0, data2, 0, data1.Length); stopwatch.Peek("Array.ConstrainedCopy: byte[] -> byte[]"); Buffer.BlockCopy(data1, 0, data2, 0, data2.Length); stopwatch.Peek("Buffer.BlockCopy: byte[] -> byte[]"); IntPtr dest1 = Marshal.AllocHGlobal(size); IntPtr dest2 = Marshal.AllocHGlobal(size); stopwatch.Peek("Marshal.AllocHGlobal"); Marshal.Copy(data1, 0, dest1, data1.Length); stopwatch.Peek("Marshal.Copy: byte[] -> IntPtr"); CopyMemory(dest2, dest1, (uint)size); stopwatch.Peek("CopyMemory: IntPtr -> IntPtr"); Marshal.Copy(dest2, data2, 0, data2.Length); stopwatch.Peek("Marshal.Copy: IntPtr -> byte[]"); } }
12:11:46.9739 [INFO] 内存操作:开始 [0ms]
12:11:46.9999 [INFO] 内存操作:分配 [3->3ms]
12:11:47.5391 [INFO] 内存操作:赋值 [539->542ms]
12:11:47.8350 [INFO] 内存操作:Array.Copy: byte[] -> byte[] [296->838ms]
12:11:47.9069 [INFO] 内存操作:Array.ConstrainedCopy: byte[] -> byte[] [72->910ms]
12:11:47.9762 [INFO] 内存操作:Buffer.BlockCopy: byte[] -> byte[] [69->979ms]
12:11:47.9762 [INFO] 内存操作:Marshal.AllocHGlobal [0->979ms]
12:11:48.1528 [INFO] 内存操作:Marshal.Copy: byte[] -> IntPtr [177->1156ms]
12:11:48.3209 [INFO] 内存操作:CopyMemory: IntPtr -> IntPtr [168->1324ms]
12:11:48.3996 [INFO] 内存操作:Marshal.Copy: IntPtr -> byte[] [78->1402ms]
1G内存复制,最快的方式是:Buffer.BlockCopy: byte[] -> byte[], Marshal.Copy: IntPtr -> byte[],大约用时七八十毫秒