我已经在不同的地方读过,关于使用固定块的数组之间不安全迭代的速度有多快.我试过.net 4和4.5,或多或少地实现了相同的结果.
安全比较总是更快,有时是一点点,有时几乎是一半时间,特别是在.net 4中.
安全比较总是更快,有时是一点点,有时几乎是一半时间,特别是在.net 4中.
难道我做错了什么?
class Program { public unsafe static int UnsafeCompareto2(byte[] self,byte[] other) { if (self.Length < other.Length) { return -1; } if (self.Length > other.Length) { return +1; } GCHandle selfHandle = GCHandle.Alloc(self,GCHandleType.Pinned); GCHandle otherHandle = GCHandle.Alloc(other,GCHandleType.Pinned); byte* selfPtr = (byte*) selfHandle.AddrOfPinnedobject().ToPointer(); byte* otherPtr = (byte*) otherHandle.AddrOfPinnedobject().ToPointer(); int length = self.Length; int comparison = 0; for (int index = 0; index < length; index++) { comparison = (*selfPtr++).Compareto((*otherPtr++)); if (comparison != 0) { break; } } selfHandle.Free(); return comparison; } public static int Compareto(byte[] self,byte[] other) { if (self.Length < other.Length) { return -1; } if (self.Length > other.Length) { return +1; } int comparison = 0; for (int i = 0; i < self.Length && i < other.Length; i++) { if ((comparison = self[i].Compareto(other[i])) != 0) { return comparison; } } return comparison; } public unsafe static int UnsafeCompareto(byte[] self,byte[] other) { if (self.Length < other.Length) { return -1; } if (self.Length > other.Length) { return +1; } int n = self.Length; fixed (byte* selfPtr = self,otherPtr = other) { byte* ptr1 = selfPtr; byte* ptr2 = otherPtr; while (n-- > 0) { int comparison; if ((comparison = (*ptr1++).Compareto(*ptr2++)) != 0) { return comparison; } } } return 0; } static void Main(string[] args) { byte[] b1 = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 }; byte[] b2 = { 1,21 }; Stopwatch watch = new Stopwatch(); watch.Start(); int result; for(long i = 0; i < Math.Pow(10,2); i++) result = Compareto(b1,b2); watch.Stop(); Console.WriteLine("safe = {0}",watch.Elapsed); watch.Restart(); for (long i = 0; i < Math.Pow(10,2); i++) result = UnsafeCompareto(b1,b2); watch.Stop(); Console.WriteLine("unsafe1 = {0}",2); i++) result = UnsafeCompareto2(b1,b2); watch.Stop(); Console.WriteLine("unsafe2 = {0}",watch.Elapsed); Console.ReadLine(); } }
解决方法
在我看来,差异经常被开销和随机噪声所淹没.我发现它对于更多的迭代更加突出,更重要的是更长的字节数组.我通过更频繁地避免方法调用开销来制作一个更快的变体:
public unsafe static int UnsafeCompareto(byte[] self,byte[] other) { if (self.Length < other.Length) { return -1; } if (self.Length > other.Length) { return +1; } int n = self.Length; fixed (byte* selfPtr = self,otherPtr = other) { byte* ptr1 = selfPtr; byte* ptr2 = otherPtr; byte b1; byte b2; while (n-- > 0) { b1 = (*ptr1++); b2 = (*ptr2++); if (b1 == b2) continue; return b1.Compareto(b2); } } return 0; }
我还注意到你的代码中有一个错误(不会真的减慢速度),如下所示:
GCHandle otherHandle = GCHandle.Alloc(self,GCHandleType.Pinned);
它应该是使用其他的,它应该在之后释放它.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。