gpt4 book ai didi

c# - 安全比较与不安全,byte[]

转载 作者:行者123 更新时间:2023-11-30 12:47:36 25 4
gpt4 key购买 nike

我在不同的地方读到过,关于使用固定 block 的数组之间的不安全迭代要快多少。我在 .net 4 和 4.5 中尝试过,或多或少地获得了相同的结果。
安全比较总是更快,有时快一点,有时快一半,特别是在 .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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 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}", watch.Elapsed);
watch.Restart();
for (long i = 0; i < Math.Pow(10, 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);

应该是用了other,之后应该是free了。

关于c# - 安全比较与不安全,byte[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16453635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com