bytes array handling compare


namespace Microshaoft
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    class Program
    {
        static int[] bufsizes = 
                            {
                                256,
                                320 * 240 * 3,
                                1024 * 768 * 3
                            };
        static int bufsize;
        const long duration = 10 * 1000 * 1000 * 10;    // 10 seconds
        static void Main(string[] args)
        {
            foreach (var b in bufsizes)
            {
                bufsize = b;
                Console.WriteLine("allocs of size " + bufsize);
                newbyte();
                marshallallochglobal();
                marshallAllocCoTaskMem();
                stackallocate();
                sharedmem();
                Console.WriteLine("memcopies of size " + bufsize);
                arraycopy();
                BufferBlockCopy();
                marshalcopy();
                kernelcopy();
                OwnMemCopyInt();
                OwnMemCopyLong();
                Console.WriteLine();
            }
            Console.WriteLine("done");
            Console.ReadLine();
        }
        private static void BufferBlockCopy()
        {
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                Buffer.BlockCopy(buf1, 0, buf2, 0, bufsize);
                i++;
            }
            Console.WriteLine("Buffer.BlockCopy: " + i);
        }
        unsafe private static void marshalcopy()
        {
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            fixed (byte* b1 = &buf1[0])
            fixed (byte* b2 = &buf2[0])
            {
                IntPtr ab2 = new IntPtr(b2);
                while ((start + duration) > DateTime.UtcNow.Ticks)
                {
                    Marshal.Copy(buf1, 0, ab2, buf1.Length);
                    i++;
                }
            }
            Console.WriteLine("Marshal.Copy: " + i);
        }
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
        public unsafe static extern void CopyMemory(byte* Destination, byte* Source, [MarshalAs(UnmanagedType.U4)] uint Length);
        unsafe private static void kernelcopy()
        {
            Console.Write("Kernel32NativeMethods.CopyMemory: ");
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            fixed (byte* b1 = &buf1[0])
            fixed (byte* b2 = &buf2[0])
            {
                while ((start + duration) > DateTime.UtcNow.Ticks)
                {
                    CopyMemory(b2, b1, (uint)buf1.Length);
                    i++;
                }
            }
            Console.WriteLine(i);
        }
        unsafe private static void OwnMemCopyInt()
        {
            Console.Write("OwnMemCopyInt: ");
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            fixed (byte* b1 = &buf1[0])
            fixed (byte* b2 = &buf2[0])
            {
                IntPtr ab1 = new IntPtr(b1);
                IntPtr ab2 = new IntPtr(b2);
                while ((start + duration) > DateTime.UtcNow.Ticks)
                {
                    MemCopyInt(ab1, ab2, buf1.Length);
                    i++;
                }
            }
            Console.WriteLine(i);
        }
        unsafe private static void OwnMemCopyLong()
        {
            Console.Write("OwnMemCopyLong: ");
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            fixed (byte * b1 = &buf1[0])
            fixed (byte * b2 = &buf2[0])
            {
                IntPtr ab1 = new IntPtr(b1);
                IntPtr ab2 = new IntPtr(b2);
                while ((start + duration) > DateTime.UtcNow.Ticks)
                {
                    MemCopyLong(ab1, ab2, buf1.Length);
                    i++;
                }
            }
            Console.WriteLine(i);
        }
        private static void arraycopy()
        {
            Console.Write("Array.Copy: ");
            byte[] buf1 = new byte[bufsize];
            byte[] buf2 = new byte[bufsize];
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                Array.Copy(buf1, buf2, buf1.Length);
                i++;
            }
            Console.WriteLine(i);
        }
        private static void newbyte()
        {
            Console.Write("new byte[]: ");
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                byte[] buf = new byte[bufsize];
                i++;
            }
            //GC.Collect();
            Console.WriteLine(i);
        }
        private static void marshallallochglobal()
        {
            Console.Write("Marshal.AllocHGlobal: ");
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                IntPtr p = Marshal.AllocHGlobal(bufsize);
                Marshal.FreeHGlobal(p);
                i++;
            }
            Console.WriteLine(i);
        }
        private static void marshallAllocCoTaskMem()
        {
            Console.Write("Marshal.AllocCoTaskMem: ");
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                IntPtr p = Marshal.AllocCoTaskMem(bufsize);
                Marshal.FreeCoTaskMem(p);
                i++;
            }
            Console.WriteLine(i);
        }
        private static void sharedmem()
        {
            try
            {
                Console.Write("SharedMemory: ");
                long start = DateTime.UtcNow.Ticks;
                int i = 0;
                while ((start + duration) > DateTime.UtcNow.Ticks)
                {
                    using (SharedMemory m = new SharedMemory("abc", bufsize, true))
                    {
                        i++;
                    }
                }
                Console.WriteLine(i);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        private static void stackallocate()
        {
            Console.Write("stackalloc: ");
            long start = DateTime.UtcNow.Ticks;
            int i = 0;
            while ((start + duration) > DateTime.UtcNow.Ticks)
            {
                stack();
                i++;
            }
            Console.WriteLine(i);
        }
        unsafe static void stack()
        {
            byte* buf = stackalloc byte[bufsize];
        }
        static public unsafe void MemCopyInt(IntPtr pSource, IntPtr pDest, int Len)
        {
            unchecked
            {
                int count = Len / Marshal.SizeOf(typeof(int));
                int rest = Len % count;
                int* ps = (int*) pSource.ToPointer(), pd = (int*) pDest.ToPointer();
                // Loop over the cnt in blocks of 4 bytes, copying an integer (4 bytes) at a time:
                for (int n = 0; n < count; n++)
                {
                    * pd++ = * ps++;
                }
                // Complete the copy by moving any bytes that weren't moved in blocks of 4:
                if (rest > 0)
                {
                    byte * ps1 = (byte*)ps;
                    byte * pd1 = (byte*)pd;
                    for (int n = 0; n < rest; n++)
                    {
                        *pd1++ = *ps1++;
                    }
                }
            }
        }
        static public unsafe void MemCopyLong(IntPtr pSource, IntPtr pDest, int Len)
        {
            unchecked
            {
                int count = Len / Marshal.SizeOf(typeof(long));
                int rest = Len % count;
                long* ps = (long*)pSource.ToPointer(), pd = (long*)pDest.ToPointer();
                // Loop over the cnt in blocks of n bytes, copying an long (n bytes) at a time:
                for (int n = 0; n < count; n++)
                {
                    *pd++ = *ps++;
                }
                // Complete the copy by moving any bytes that weren't moved in blocks of n:
                if (rest > 0)
                {
                    byte* ps1 = (byte*) ps;
                    byte* pd1 = (byte*) pd;
                    for (int n = 0; n < rest; n++)
                    {
                        * pd1 = * ps1;
                        pd1++;
                        ps1++;
                    }
                }
            }
        }
    }
    unsafe public class SharedMemory : IDisposable
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, PageProtection flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName);
        const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        const UInt32 SECTION_QUERY = 0x0001;
        const UInt32 SECTION_MAP_WRITE = 0x0002;
        const UInt32 SECTION_MAP_READ = 0x0004;
        const UInt32 SECTION_MAP_EXECUTE = 0x0008;
        const UInt32 SECTION_EXTEND_SIZE = 0x0010;
        const UInt32 SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE);
        const UInt32 FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS;
        [Flags]
        enum PageProtection : uint
        {
            NoAccess = 0x01,
            Readonly = 0x02,
            ReadWrite = 0x04,
            WriteCopy = 0x08,
            Execute = 0x10,
            ExecuteRead = 0x20,
            ExecuteReadWrite = 0x40,
            ExecuteWriteCopy = 0x80,
            Guard = 0x100,
            NoCache = 0x200,
            WriteCombine = 0x400,
        }
        private IntPtr hHandle;
        public void * Buffer
                        {
                            get;
                            private set;
                        }
        public int Length { get; private set; }
        public SharedMemory(string name, int size, bool create)
        {
            if (create)
            {
                Create(name, size);
            }
            else
            {
                Attach(name);
            }
        }
        ~SharedMemory()
        {
            Detach();
        }
        private void Create(string SharedMemoryName, int NumBytes)
        {
            hHandle = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, PageProtection.ReadWrite, 0, (uint)NumBytes, SharedMemoryName);
            if (IntPtr.Zero == hHandle)
            {
                throw new InvalidOperationException(String.Format("Failed to create FileMapping with given name '{0}'.", SharedMemoryName));
            }
            Buffer = MapViewOfFile(hHandle, FILE_MAP_ALL_ACCESS, 0, 0, IntPtr.Zero).ToPointer();
            Length = NumBytes;
        }
        private void Attach(string SharedMemoryName)
        {
            hHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, SharedMemoryName);
            if (IntPtr.Zero == hHandle)
            {
                throw new InvalidOperationException(String.Format("Failed to open FileMapping with given name '{0}'.", SharedMemoryName));
            }
            Buffer = MapViewOfFile(hHandle, FILE_MAP_ALL_ACCESS, 0, 0, IntPtr.Zero).ToPointer();
        }
        private void Detach()
        {
            if (IntPtr.Zero != hHandle)
            {
                UnmapViewOfFile(new IntPtr(Buffer));
                CloseHandle(hHandle); //fair to leak if can't close
                hHandle = IntPtr.Zero;
            }
            Buffer = IntPtr.Zero.ToPointer();
        }
        #region IDisposable Members
        public void Dispose()
        {
            Detach();
        }
        #endregion
    }
}

posted @ 2009-02-10 22:51  于斯人也  阅读(9490)  评论(0编辑  收藏  举报