c-如果和其他,我应该放更可能的部分



我想知道语言之间是否存在很大的性能差异,是应该将更有可能执行的代码放在if子句中还是放在else子句中。这里有一个例子:

// x is a random number, or some key code from the user
if(!somespecific_keycode)
   do the general stuff
else
   do specific stuff

另一种解决方案

if(somespecific_keycode)
   do the specific stuff
else
   do general stuff

更喜欢将它们按使代码更清晰的顺序排列,这通常更有可能首先执行。

正如其他人所说:就性能而言,您最好依靠编译器和硬件(分支预测、推测执行)来做正确的事情。

如果您真的担心这两个对您的帮助不够,GCC提供了一个内建函数(__builtin_expect),您可以用它显式地指示分支的预期结果。

就代码可读性而言,我个人喜欢最有可能的情况。

除非遇到性能问题,否则不要担心。

如果您确实遇到了性能问题,请尝试切换它们,测量哪种变体更快(如果有的话)。

通常的规则是把更可能的情况放在第一位,它被认为更可读。

分支预测将导致其中一个更有可能,并且如果在循环中,它将导致性能差异。但大多数情况下,如果您不是在汇编程序级别思考,您可以忽略这一点。

这不一定是性能问题,但我通常会从特定到一般,以防止出现以下情况:

int i = 15;
if(i % 3 == 0)
   System.out.println("fizz");
else if(i % 5 == 0)
   System.out.println("buzz");
else if(i % 3 == 0 && i % 5 == 0)
   System.out.println("fizzbuzz");   

在这里,上面的代码永远不会说"fizzbuzz",因为15同时符合i % 3 == 0i % 5 == 0条件。如果你重新订购更具体的东西:

int i = 15;
if(i % 3 == 0 && i % 5 == 0)
   System.out.println("fizzbuzz");
else if(i % 3 == 0)
   System.out.println("fizz");
else if(i % 5 == 0)
   System.out.println("buzz");  

现在,在被更一般的条件

停止之前,上面的代码将达到"fizzbuzz"

所有答案都有有效点。这里还有一个:

  • 避免双重否定:如果不是这个,那么那个,否则的东西往往会让读者感到困惑。因此,对于给定的示例,我赞成:

    if (somespecific_keycode) {
        do_the_specific_stuff();
    } else {
        do_general_stuff();
    }
    

这基本上没有什么区别,但如果您的if正在检查某个值是否为真或相等,而其他if则在情况并非如此时进行处理,则有时读取和调试会更容易。

正如其他人所说,除非你多次使用它(例如在循环中),否则不会有太大的不同。在这种情况下,将最有可能的条件放在第一位,因为它将最早有机会脱离条件检查。

当你开始有很多"如果"时,它会变得更加明显。

任何可能出现的差异都与上下文有关,而不是与if-else构造固有的差异。因此,在这里你能做的最好的事情就是开发自己的测试来检测任何差异。

除非您正在优化已经完成的系统或软件,否则我建议您避免过早优化。也许你已经听说他们是邪恶的。

AFAIK使用现代优化C编译器,如何组织if或循环与生成代码中的实际分支指令之间没有直接关系。此外,不同的CPU具有不同的分支预测算法。

因此:

  • 在您看到与此代码相关的糟糕性能之前,不要进行优化

  • 如果您确实优化、测量和比较了不同版本的

  • 使用各种特性的真实数据进行性能测量

  • 查看编译器在这两种情况下生成的汇编代码。

相关内容

  • 没有找到相关文章

最新更新