c#执行速度:相等(==)vs不相等(!=)

本文关键字:vs 不相等 执行 速度 相等 | 更新日期: 2023-09-27 18:19:18

我正试图找出一些if语句的最佳实践。当我需要打开一些等式,即需要一个if-else结构时,我通常在"不相等"上写条件。这背后的原因是,通常,当一个不成功的结果出现时,指令的数量和它们的复杂性都很低。在比较过程中有什么不同吗?相等(==)和不相等(!=)在执行时间上有区别吗?

示例(一个相当简单的示例,但总体思想是成立的):

string myString = "weekend";
if(myString != "weekend")
{
    Console.WriteLine("No fun...!");
}
else
{
    //do a bunch of fun stuff with relatively high complexity
    //can expand over many lines of code
}

如果我改变if-else语句的顺序,执行时间会有什么不同吗?

string myString = "weekend";
if(myString == "weekend")
{        
    //do a bunch of fun stuff with relatively high complexity
    //can expand over many lines of code
}
else
{
    Console.WriteLine("No fun...!");
}

c#执行速度:相等(==)vs不相等(!=)

首先,其他的答案说(1)担心重要的事情,(2)以看起来最好的方式编写代码,(3)如果你真的关心,测量它,是正确的。

总而言之,重要的是要意识到编译器被允许以任何方式生成你的代码,只要意思被保留,编译器经常改变if中布尔值的"符号",这样他们就可以生成更好的代码。请记住,当编译器将c#翻译成IL,并且抖动将IL翻译成机器码时,将不会有if语句。只需要在堆栈上生成一个bool值;现在跳转如果bool值为true/false"在IL中,或者"将bool值放入寄存器中;现在,如果寄存器在机器码中为零/非零",则跳转。

当你说:

if (A())  
    B();
C();

编译器可以生成这些指令的等价物:

call A()
if last result is false then goto SKIP
call B()
SKIP: call C()

或者它可以很容易地生成:

call A()
if last result is true then goto CONSEQUENCE
goto SKIP
CONSEQUENCE: call B()
SKIP: call C()

请注意,第一个版本,它反转了测试的符号,比第二个版本短一条指令,因此更有可能是由一个优化编译器生成的,它试图保持你的代码简短。

在这种精神下,允许编译器选择比较是否相等而不是不相等,并反转测试的符号,当这样做可以生成更好的代码时。同样,c#编译器有时会将if (A() <= B())转换为if (!(A() > B()),反之亦然,如果这样做不会改变程序的意义,并且一个版本比另一个版本短。 我的观点是,从相等变为不相等可能不会对生成的代码产生任何影响,因为编译器会自动将您的代码重写为更好的版本。相信编译器会完成它的工作,担心其他的事情吧。

我认为你应该用最易读的方式来写。这样的微优化不太可能对您的代码产生任何可察觉的差异:每次比较您最多谈论一个"not"操作。如果这是一个显著的差异,那么编译器可能会优化它,但实际上这甚至没有什么值得考虑的。

在普通处理器上,如果相等跳转和如果不相等跳转指令在内存和速度方面非常相似。这是假设编译器没有优化消除语法差异。

我只是想说一下....

如果这段代码已经在它自己的函数中,我将只执行检查,然后返回,如果我不想执行其余的代码。像这样:

void PointlessExample(){
    string myString = "weekend";
    if(myString != "weekend")
    {
        Console.WriteLine("No fun...!");
        return;
    }
    //rest of the code
}

我建议将您的高复杂性逻辑转移到一个单独的方法中,从而抽象逻辑,并简化您的方法。

string myString = "weekend";
if(myString == "weekend")
{        
    ComplexMethod();
}
else
{
    Console.WriteLine("No fun...!");
}

这样一来,无论你往哪个方向写if语句都无关紧要。


在性能方面,我认为您不会发现==!=之间有任何显着差异。

由于在性能上没有真正的区别(只有在非常非常紧密的循环中才会有真正的影响),我强烈建议不要"标准化"==或!=,而只是在这种情况下使用有意义的东西。

我通常把较小的大小写放在前面,否则你会在代码末尾看到一堆挂括号。

if (number != 1337) 
{
    Console.Writeline("Nope")
}
else 
{
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
}

相对
if (number == 1337) 
{
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
}
else 
{
    Console.Writeline("Nope")
}

有些人喜欢把动作放在前面,边缘情况放在后面(说这更像是try {} catch{}) -所以这更多的是风格问题,而不是最佳实践问题。

如果做很多事情变得笨拙,那么你可能要考虑把它包装在一个函数中,这意味着无论你把项目的顺序是什么

if (number == 1337) 
{
     DoLotsOfStuff();
}
else 
{
    Console.Writeline("Nope")
}