gpt4 book ai didi

c# - 为什么在比较两个可空值是否相等时不使用短路逻辑 'and' 运算符?

转载 作者:太空狗 更新时间:2023-10-29 21:07:46 25 4
gpt4 key购买 nike

我有一个比较两个可为空的整数并将比较结果打印到控制台的方法:

static void TestMethod(int? i1, int? i2)
{
Console.WriteLine(i1 == i2);
}

这是它的反编译结果:

private static void TestMethod(int? i1, int? i2)
{
int? nullable = i1;
int? nullable2 = i2;
Console.WriteLine((nullable.GetValueOrDefault() == nullable2.GetValueOrDefault()) & (nullable.HasValue == nullable2.HasValue));
}

结果或多或少符合我的预期,但我想知道为什么使用逻辑“与”运算符 (&) 的非短路版本而不是短路版本 (&&)。在我看来,后者会更有效率——如果已知比较的一侧是错误的,那么就没有必要评估另一侧。 & 运算符在这里是必需的还是这只是一个不够重要的实现细节?

最佳答案

The result is more less what I expected but I wonder why non-short-circuit version of logical and operator (&) is used instead of short-circuit version (&&). It seems to me that the latter would be more efficient - if one side of comparison is already known then there is no need to evaluate the other side. Is there a reason that mandates usage of & operator or this is just implementation detail that is not important enough to bother?

这是一个很好的问题。

首先,我为 Roslyn 之前的可空降低代码和 Roslyn 中的原始实现开发了代码生成器。这是一些棘手的代码,有很多错误和错过优化的机会。我写了一系列关于 Roslyn 可空降低优化器如何工作的博客文章,文章从这里开始:

https://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/

如果您对这个主题感兴趣,那么本系列文章可能会有很大帮助。第三部分特别相关,因为它讨论了一个相关问题:对于可空算术,我们是否生成 (x.HasValue & y.HasValue) ? new int?(x.Value + y.Value) : new int?() 或使用 && 或使用 GetValueOrDefault 还是什么? (答案当然是我尝试了所有这些并选择了最快的最小代码。)然而,该系列没有考虑您在这里的具体问题,即关于可为空的平等。可空相等的规则与普通提升算术略有不同。

当然,我从2012年开始就没有在微软工作过,他们可能从那以后就换了;我不知道。 (更新:查看上面评论中的链接问题,我似乎错过了 2011 年原始实现中的优化,并在 2017 年修复了这一问题。)

回答您的具体问题:&& 的问题在于当工作在右侧完成时,它比 & 更昂贵运算符的一侧比测试和分支便宜。测试和分支不仅仅是更多的指令。显然,它是一个分支,具有很多链式 react 。在处理器层面,分支需要进行分支预测,而分支是可以预测错误的。分支意味着更多的基本 block ,请记住,jit 优化器在运行时运行,这意味着 jit 优化器必须快速。允许说“此方法中的基本 block 太多,我将跳过一些优化”,因此可能不必要地添加更多基本 block 是一件坏事。

长话短说,如果右侧没有副作用,C# 编译器将生成“and”运算,编译器认为评估 left & right 会更快更短比评估 left ?对:假。通常,评估正确的成本非常低,以至于分支的成本比只进行急切的算术更昂贵

您可以在可空优化器以外的区域看到这一点;例如,如果您有

bool x = X();
bool y = Y();
bool z = x && y;

然后它将生成为 z = x & y 因为编译器知道没有要保存的昂贵操作; Y() 已经 被调用。

关于c# - 为什么在比较两个可空值是否相等时不使用短路逻辑 'and' 运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53053343/

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