【问题标题】:Performance of If/Else If versus OR-operator in C#C# 中 If/Else If 与 OR 运算符的性能
【发布时间】:2021-02-27 20:00:13
【问题描述】:

我对以不同方式形成基于 OR 的逻辑的性能影响感到好奇,因此我进行了一个简单且可能有点不科学的测试。我在 if 语句设置为 true(以触发案例 1)和设置为 false(以触发案例 2)的情况下运行了 10 次以下代码。我使用this site 测试代码并依赖其报告的“绝对运行时间”。

我得到的结果是,案例 1 的平均运行时间为 0.354 秒,而案例 2 的平均运行时间为 0.442 秒。这些数字在各个方面都相当一致——在案例 1 中,它们在 0.04 范围内变化,在案例 2 中,它们在 0.09 范围内变化,根本没有重叠,所以乍一看似乎是一个明显的差异。

这两种情况对计数器产生相同的结果 - 在这种情况下为 38571428,但我尝试的其他 toCount 值也相同。我的理解是,如果先前的 if 或 else-if 语句评估为 true,则不会评估 else-if 语句,因此从逻辑的角度来看,我认为这两种情况是在做同样的事情。

我对为什么案例 1 的性能优于案例 2 没有很好的直觉。有人可以对此有所了解吗?我对一般意义上感兴趣,为了更好地理解构建 C# 逻辑的不同方式可能会如何影响性能,所以我希望这个例子也可能有一些基本原则可以理解,但即使只是解释这个案例看起来很有趣。

int counter = 0;
int toCount = 50000000;
//Case 1
if (false)
{
    for (int iNum = 0; iNum < toCount; ++iNum)
    {
        if (iNum % 2 == 0 || iNum % 3 == 0 || iNum % 5 == 0 || iNum % 7 == 0)
        {
            ++counter;
        }
    }
}
//Case 2
else
{
    for (int iNum = 0; iNum < toCount; ++iNum)
    {
        if (iNum % 2 == 0)
        {
            ++counter;
        }
        else if (iNum % 3 == 0)
        {
            ++counter;
        }
        else if (iNum % 5 == 0)
        {
            ++counter;
        }
        else if (iNum % 7 == 0)
        {
            ++counter;
        }
    }
}
Console.WriteLine("Result: " + counter.ToString());

【问题讨论】:

  • 你编译和运行的优化级别是什么?
  • 请注意,一个真正聪明的编译器会展开 2*3*5*7 次迭代的块,发现总是导致相同数量的匹配,并且实际上只需要遍历最终的部分块。
  • 两个版本编译成different IL code:ifs明显更长,因此它的JITted汇编也更长。执行指令的数量不应该真的不同,但它足以不内联第二个版本(您可以尝试将[MethodImpl(MethodImplOptions.AggressiveInlining)] 应用于您的方法并再次检查差异)。而且也许 CPU 还可以更好地优化第一个版本的 JITted 代码的管道。

标签: c# performance if-statement syntax operators


【解决方案1】:

这取决于。您必须彻底对您的特定用例进行基准测试。但是,在不知道细节的情况下,我会说:两者都没有

首先检查生成的IL 代码和/或JIT Asm sharplap.io。它应该给你一些提示。看起来像 Case1 产生更小的代码大小。这可能会影响优化期间的内联。

您还可以尝试使用四个单独的 for 循环来尽可能提高性能。这完全取决于 CPU 缓存。这个概念之前已经讨论过。我建议您阅读这些答案/讨论:

【讨论】:

    【解决方案2】:

    if 语句和 or 语句都有其优点和缺点 if 语句是如果发生这种情况,则执行此操作,而 or 语句就像是说执行此或那样,并且您让计算机在两个 for or 语句之间做出决定。只需尝试将您的代码用简单的英语或任何您的母语编写即可。

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 2017-11-19
      • 1970-01-01
      • 2018-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-23
      • 1970-01-01
      相关资源
      最近更新 更多