在c#中把int转成byte[]一般都会使用BitConverter.GetBytes可以获取得到,但BitConverter有个问题就是每次调用都会产生一个新byte[];如果你比较执着的话以下提供两种方式可以省下这一些。
从BitConverter中把代码偷取出来,加功一下:),先看下BitConverter.GetBytes关于int的方法
1 public unsafe static byte[] GetBytes(int value) 2 { 3 byte[] array = new byte[4]; 4 fixed (byte* ptr = array) 5 { 6 *(int*)ptr = value; 7 } 8 return array; 9 }
可以改成如下:
1 public class IntToBytes2 2 { 3 private byte[] m4byteData = new byte[4]; 4 5 public unsafe byte[] ToBytes(int value) 6 { 7 fixed (byte* ptr = m4byteData) 8 { 9 *(int*)ptr = value; 10 } 11 return m4byteData; 12 } 13 }
还有一种是通过定义一个结构
1 public class IntToBytes1 2 { 3 private byte[] m4byteData = new byte[4]; 4 private Switcher mData; 5 public byte[] ToBytes(int value) 6 { 7 mData.intVal = value; 8 m4byteData[0] = mData.b0; 9 m4byteData[1] = mData.b1; 10 m4byteData[2] = mData.b2; 11 m4byteData[3] = mData.b3; 12 return m4byteData; 13 } 14 [StructLayout(LayoutKind.Explicit)] 15 struct Switcher 16 { 17 [FieldOffset(0)] 18 public int intVal; 19 [FieldOffset(0)] 20 public byte b0; 21 [FieldOffset(1)] 22 public byte b1; 23 [FieldOffset(2)] 24 public byte b2; 25 [FieldOffset(3)] 26 public byte b3; 27 } 28 }
其实还有一种就是通过移位来实现,这里就不多说。
简单测试一下效果,建议编译成Release然后单独运行exe看情况,如果不是结果可能有比较大的出入
1 IntToBytes1 t1 = new IntToBytes1(); 2 IntToBytes2 t2 = new IntToBytes2(); 3 System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 4 sw.Reset(); 5 sw.Start(); 6 for (int i = 0; i < 9999999; i++) 7 { 8 BitConverter.GetBytes(i); 9 } 10 sw.Stop(); 11 Console.WriteLine(sw.Elapsed.TotalMilliseconds); 12 sw.Reset(); 13 sw.Start(); 14 for (int i = 0; i < 9999999; i++) 15 { 16 17 t1.ToBytes(i); 18 } 19 sw.Stop(); 20 Console.WriteLine(sw.Elapsed.TotalMilliseconds); 21 sw.Reset(); 22 sw.Start(); 23 for (int i = 0; i < 9999999; i++) 24 { 25 26 t2.ToBytes(i); 27 } 28 sw.Stop(); 29 Console.WriteLine(sw.Elapsed.TotalMilliseconds);
运行结果分别是208ms,148ms和150ms。从结果上来看自定义的两种似乎要快,细心的朋友看到后应该发现这样的测试似乎不公平;首先BitConverter方法本身是线程安全的,而其他两者并不是;如果其他两种方式在每次使用的时候都定义那出来的结果就完全不一样了,估计BitConverter是最高效的(有兴趣的朋友可以方式下)。如果自定义的方式在定义后使用一定的次数显然是比BitConverter来的得价值,如在网络通讯时针对一个连接来分配后面的所有转换都使用他这样价值就能体现出来。
其实在.net framework里不仅公是BitConverter存在这情况,在我们特别常用Encoding.GetBytes都是通过这方式来处理,还有string.toCharArray等在高密集的处理时都会大量地构建新的byte[]和char[].如果你比较关心这些细节不防多看下这些对象的方法,然后通过某些途劲把这些问题解决。这不仅仅能够提高一点处理效率还能解放一些GC的工作。