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

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

概述我优化了一个扩展方法来比较两个流相等(字节到字节) – 知道这是一个热的方法,我尽可能地优化它(流可以达到多兆字节的长度).我基本上想出了以下方法: [StructLayout(LayoutKind.Explicit)]struct Converter{ [FieldOffset(0)] public Byte[] Byte; [FieldOffset(0)] 我优化了一个扩展方法来比较两个流相等(字节到字节) – 知道这是一个热的方法,我尽可能地优化它(流可以达到多兆字节的长度).我基本上想出了以下方法:
[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# – 如果在条件为假时执行语句True块全部内容,希望文章能够帮你解决c# – 如果在条件为假时执行语句True块所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1259446.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存