using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace BlittableStructure { static class Program { delegate uint SizeOfType(Type type); static SizeOfType SizeOf = typeof(Marshal).GetMethod("SizeOfType", BindingFlags.NonPublic | BindingFlags.Static).CreateDelegate(typeof(SizeOfType)) as SizeOfType; static class Blittable where T : struct { public static readonly int Size = (int)SizeOf(typeof(T)); public static readonly unsafe void* Handle = typeof(T).TypeHandle.Value.ToPointer(); } [FixedAddressValueType] static readonly unsafe void* handle = typeof(Array).TypeHandle.Value.ToPointer(), type = typeof(byte[]).TypeHandle.Value.ToPointer(); [MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.IL)] static unsafe T Read(this Stream input) where T : struct { var size = Blittable.Size; var tref = stackalloc byte[IntPtr.Size * 5 + size]; var inst = (void**)tref + 3; inst[1] = (void*)size; inst[0] = handle; inst[-2] = type; inst[-3] = &inst; if(input.Read( __refvalue(*(TypedReference*)tref, byte[]), 0, size) < size) throw new EndOfStreamException(); inst[-3] = inst + 2; inst[-2] = Blittable.Handle; return __refvalue( *(TypedReference*)tref,T); } /// /// アプリケーションのメイン エントリ ポイントです。 /// [STAThread] static unsafe void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); try { var i = 100000; var stack = stackalloc int[i]; stack[1] = 1; stack[2] = 2; stack[3] = 3; stack[4] = 4; using(var mem = new UnmanagedMemoryStream((byte*)stack, sizeof(int) * i)) using(var bin = new BinaryReader(mem, Encoding.ASCII, true)) { var sw = Stopwatch.StartNew(); mem.Read(); Console.WriteLine(mem.Read()); mem.Seek(0L, SeekOrigin.Begin); sw.Restart(); while(--i >= 0) mem.Read(); Console.WriteLine(sw.ElapsedTicks); i = 100000; mem.Seek(0L, SeekOrigin.Begin); sw.Restart(); while(--i >= 0) bin.ReadInt32(); Console.WriteLine(sw.ElapsedTicks); } } catch(Exception e) { Console.WriteLine(e); } } } }