假设编译器实际上是内联foo
的,这两个语句之间是否存在性能差异?
inline int foo (int val) {
return val;
}
int main () {
std::cout << foo(123) << std::endl;
std::cout << 123 << std::endl;
return 0;
}
让我们忽略移动语义和复制省略可能产生的任何影响。
我的编译器(gcc 4.7.2)为这两个语句生成几乎相同的代码:
_main:
LFB1018:
pushq %rbx
LCFI0:
movq __ZSt4cout@GOTPCREL(%rip), %rbx
; std::cout << foo(123) << std::endl;
movl $123, %esi
movq %rbx, %rdi
call __ZNSolsEi
movq %rax, %rdi
call __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
; std::cout << 123 << std::endl;
movq %rbx, %rdi
movl $123, %esi
call __ZNSolsEi
movq %rax, %rdi
call __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
xorl %eax, %eax
popq %rbx
LCFI1:
ret
唯一的区别是前两条指令的顺序。我已经对它进行了实验,这种差异似乎与以下内容没有任何关系foo()
:如果我将这两行重复两次,则只有四个语句中的最后一个语句的指令顺序颠倒了。这让我觉得这个工件可能与管道优化器或类似的东西有关。
应该是完全一样的。
为确保确实如此,请使用-S
gcc 中的标志生成汇编代码并手动比较这两行。
另外,请注意 inline 关键字只是对编译器的提示,编译器可能会选择忽略它。这个问题对使用内联有深入的讨论。