C#执行速度:等于(==)vs不等于(!=)

时间:2013-06-21 13:46:21

标签: c# optimization if-statement

我正在试图找出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...!");
}

6 个答案:

答案 0 :(得分:14)

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

所有人都说,重要的是要认识到只要保留了意义,编译器就可以以任何方式生成代码,并且编译器经常更改{{}中布尔值的“符号”。 1}}这样他们就可以生成更好的代码。请记住,当编译器将C#转换为IL,并且抖动将IL转换为机器代码时,将不会有if语句。在IL中,只有“在堆栈上生成一个bool;如果bool为真/假则跳转”,或者“在寄存器中放置一个bool;如果寄存器为零/非零,则在机器代码中跳转”。

当你说:

if

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

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

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

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

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

在这种精神下,允许编译器选择比较相等而不是不等,并反转测试的符号,这样做会产生更好的代码。同样,C#编译器有时会将call A() if last result is true then goto CONSEQUENCE goto SKIP CONSEQUENCE: call B() SKIP: call C() 转换为if (A() <= B()),反之亦然,这样做不会改变程序的含义,并且当一个版本比另一个版本短时。

我的观点是,从平等到不平等的转变可能在生成的代码中根本没有任何区别,因为编译器会自动将代码重写为更好的版本。相信编译器可以完成它的工作,并担心别的事情。

答案 1 :(得分:11)

我会说你应该以最可读的方式写它。这样的微优化根本不可能对您的代码产生任何可辨别的差异:您最多只讨论 每次比较一次“非”操作。如果它是一个显着的差异,那么编译器可能无论如何都会优化它,但实际上这甚至都没有想到。

答案 2 :(得分:2)

在普通处理器上,如果内存和速度相同,则跳跃如果相等且跳转如果不相等的指令非常相似。而且假设编译器没有优化语法差异。

答案 3 :(得分:2)

以为我会说我的话......

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

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

    //rest of the code
}

答案 4 :(得分:1)

我建议将高复杂度逻辑转换为单独的方法,从而抽象出逻辑,并简化方法。

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

这样你编写if语句的方式无关紧要。


就业绩而言,我认为您不会发现==!=之间存在任何重大差异。

答案 5 :(得分:1)

由于性能没有真正的差异(如果你处于一个非常非常紧凑的循环中它只会真的很重要),我强烈建议不要在==或!=上“标准化”,而只是去做什么在这种情况下是有道理的。

我通常首先放置较小的案例,否则最终会在代码末尾添加许多悬挂括号。

e.g。

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")
}