Created
July 24, 2019 09:05
-
-
Save harujoh/628e84de36f0d430ceabdcdc5a8be591 to your computer and use it in GitHub Desktop.
ネイティブからネイティブへのコピー速度比較
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
namespace ConsoleApp75 | |
{ | |
class Program | |
{ | |
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")] | |
private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length); | |
static unsafe void Main(string[] args) | |
{ | |
const int size = 1073741824; | |
const int count = 100; | |
IntPtr ptr = Marshal.AllocCoTaskMem(size); | |
IntPtr ptr2 = Marshal.AllocCoTaskMem(size); | |
byte[] bytes = Enumerable.Repeat((byte)128, size).ToArray(); | |
using (MemoryStream streamSrc = new MemoryStream(bytes)) | |
using (UnmanagedMemoryStream streamDst = new UnmanagedMemoryStream((byte*)ptr, size, size, FileAccess.Write)) | |
streamSrc.CopyTo(streamDst); | |
Console.WriteLine("Performing tests on copying {0} megabytes of memory.", size / (double)1024 / 1024); | |
GC.Collect(); | |
Stopwatch watch = new Stopwatch(); | |
// make sure methods are JIT’d (they probably are, since there | |
// should be native images of the standard library, but just to be safe..) | |
watch.Reset(); | |
watch.Start(); | |
watch.Stop(); | |
double averageTime = 0; | |
{ | |
watch.Reset(); | |
watch.Start(); | |
{ | |
using (UnmanagedMemoryStream streamSrc = new UnmanagedMemoryStream((byte*)ptr, size, size, FileAccess.Read)) | |
using (UnmanagedMemoryStream streamDst = new UnmanagedMemoryStream((byte*)ptr2, size, size, FileAccess.Write)) | |
{ | |
for (int i = 0; i < count; i++) | |
{ | |
streamSrc.Position = 0; | |
streamDst.Position = 0; | |
streamSrc.CopyTo(streamDst); | |
} | |
} | |
} | |
watch.Stop(); | |
averageTime = watch.ElapsedMilliseconds / (double)count; | |
Console.WriteLine("Average time for Stream is {0} ms.", averageTime); | |
} | |
{ | |
watch.Reset(); | |
watch.Start(); | |
for (int i = 0; i < count; i++) | |
{ | |
CopyMemory(ptr2, ptr, size); | |
} | |
watch.Stop(); | |
averageTime = watch.ElapsedMilliseconds / (double)count; | |
Console.WriteLine("Average time for API is {0} ms.", averageTime); | |
} | |
{ | |
watch.Reset(); | |
watch.Start(); | |
for (int i = 0; i < count; i++) | |
{ | |
Buffer.MemoryCopy((void*)ptr, (void*)ptr2, size, size); | |
} | |
watch.Stop(); | |
averageTime = watch.ElapsedMilliseconds / (double)count; | |
Console.WriteLine("Average time for Buffer is {0} ms.", averageTime); | |
} | |
{ | |
watch.Reset(); | |
watch.Start(); | |
int* src = (int*)ptr; | |
int* dest = (int*)ptr2; | |
for (int j = 0; j < count; j++) | |
{ | |
for (int i = 0; i < size / sizeof(int); i++) | |
{ | |
dest[i] = src[i]; | |
} | |
} | |
watch.Stop(); | |
averageTime = watch.ElapsedMilliseconds / (double)count; | |
Console.WriteLine("Average time int copy is {0} ms.", averageTime); | |
} | |
Marshal.FreeHGlobal(ptr); | |
Marshal.FreeHGlobal(ptr2); | |
Console.WriteLine("Done."); | |
Console.ReadKey(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment