分配临时变量或计算表达式两次

Tan*_*ura 4 c c++

我试图尽可能高效地编写代码,我遇到了以下情况:

int foo(int a, int b, int c) 
{
    return (a + b) % c; 
}
Run Code Online (Sandbox Code Playgroud)

都好!但是,如果我想检查表达式的结果是否与常量不同,那该怎么办呢myConst.可以说我可以负担一个临时变量.

什么方法是以下最快的方法:

int foo(int a, int b, int c) 
{
    return (((a + b) % c) != myConst) ? (a + b) % c : myException; 
} 
Run Code Online (Sandbox Code Playgroud)

要么

int foo(int a, int b, int c) 
{
    int tmp = (a + b) % c
    return (tmp != myConst) ? tmp : myException; 
}
Run Code Online (Sandbox Code Playgroud)

我无法决定.'line'在哪里重新计算比分配和释放临时变量更昂贵,反之亦然.

Ser*_*eyA 14

不要担心,编写简洁的代码并将微优化保留给编译器.

在您的示例中,编写两次相同的计算很容易出错 - 所以不要这样做.在您的具体示例中,编译器很可能完全避免在堆栈上创建临时值!

您的示例可以(在我的编译器上)生成以下程序集(我已替换myConstconstexpr42和myException0):

foo(int, int, int):
        leal    (%rdi,%rsi), %eax       # this adds a and b, puts result to eax
        movl    %edx, %ecx      # loads c
        cltd
        idivl   %ecx  # performs division, puts result into edx
        movl    $0, %eax        #, prepares to return exception value
        cmpl    $42, %edx       #, compares result of division with magic const
        cmovne  %edx, %eax  # overwrites pessimized exception if all is cool
        ret
Run Code Online (Sandbox Code Playgroud)

如你所见,在任何地方都没有临时的!


dbu*_*ush 6

使用以后的.

  1. 你没有计算两次相同的值.
  2. 代码更清晰.
  3. 在堆栈上创建局部变量不会花费任何大量时间.


usr*_*301 5

检查为两个版本生成的汇编代码.您最有可能希望编译器具有最高的优化设置.

你可能很好地发现编译器本身可以弄清楚中间值是否使用了两次,但只在函数内部,因此可以安全地存储在寄存器中.