c# – 如果在条件为假时执行语句True块

前端之家收集整理的这篇文章主要介绍了c# – 如果在条件为假时执行语句True块前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我优化了一个扩展方法来比较两个流相等(字节到字节) – 知道这是一个热的方法,我尽可能地优化它(流可以达到多兆字节的长度).我基本上想出了以下方法
[StructLayout(LayoutKind.Explicit)]
struct Converter
{
    [FieldOffset(0)]
    public Byte[] Byte;

    [FieldOffset(0)]
    public UInt64[] UInt64;
}

/// <summary>
/// Compares two streams for byte-by-byte equality.
/// </summary>
/// <param name="target">The target stream.</param>
/// <param name="compareTo">The stream to compare the target to.</param>
/// <returns>A value indicating whether the two streams are identical.</returns>
public static bool CompareBytes(this Stream target,Stream compareTo)
{
    if (target == null && compareTo == null)
        return true;
    if (target == null || compareTo == null)
        return false;
    if (target.Length != compareTo.Length)
        return false;
    if (object.ReferenceEquals(target,compareTo))
        return true;
    if (!target.CanRead || !target.CanSeek)
        throw new ArgumentOutOfRangeException("target");
    if (!compareTo.CanRead || !compareTo.CanSeek)
        throw new ArgumentOutOfRangeException("target");
    lock (target)
    {
        lock (compareTo)
        {
            var origa = target.Position;
            var origb = compareTo.Position;
            try
            {
                target.Position = compareTo.Position = 0;

                // Shrink the number of comparisons.
                var arr1 = new byte[4096];
                var convert1 = new Converter() { Byte = arr1 };
                var arr2 = new byte[4096];
                var convert2 = new Converter() { Byte = arr2 };

                int len;
                while ((len = target.Read(arr1,4096)) != 0)
                {
                    if (compareTo.Read(arr2,4096) != len)
                        return false;
                    for (var i = 0; i < (len / 8) + 1; i++)
                        if (convert1.UInt64[i] != convert2.UInt64[i])
                            return false;
                }

                return true;
            }
            finally
            {
                target.Position = origa;
                compareTo.Position = origb;
            }
        }
    }
}

问题是convert1.UInt64 [i]!= convert2.UInt64 [i]如果正在评估block(返回false),即使值相等.我单独检查了每一个,然后检查“不平等”的结果.我完全不敢相信

我没有弄错指令指针 – 这是代码执行和手表引脚是活的.

任何想法如何发生?

解决方法

for (var i = 0; i < (len / 8) + 1; i++)

调试器通常与这个联合很困难,当我尝试它时不能显示数组内容.但核心问题无疑是for()结束表达式中的1个.当len可被8除以时,将数组索引到其最后一个元素之外.运行时无法捕获此错误,重叠数组会导致Length属性具有伪造值.接下来发生的是未定义的行为,您正在读取不属于数组的字节.解决方法是使数组7字节更长.

这种代码不是一个优化,阅读和比较uint64在32位机器上是昂贵的,特别是当数组不正确对齐时.大约50%的可能性.更好的捕鼠器是使用C运行时memcmp()函数,可在任何Windows机器上使用:

[DllImport("msvcrt.dll")]
    private static extern int memcmp(byte[] arr1,byte[] arr2,int cnt);

并使用它:

int len;
    while ((len = target.Read(arr1,4096)) != 0) {
        if (compareTo.Read(arr2,4096) != len) return false;
        if (memcmp(arr1,arr2,len) != 0) return false;
    }
    return true;

比较这个的perf和一个比较字节的()循环.这里的最终节流是存储器总线带宽.

猜你在找的C#相关文章