这是 g++ 在将 -O3 标志用于通过引用返回整数的方法时默认生成的:
void Foo(int& rc) {
rc = 42;
}
变成:
__Z3FooRi:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $42, (%rdi)
popq %rbp
ret
Leh_func_end1:
这是按值返回的相同方法:
int Foo() {
return 42;
}
变成:
__Z3Foov:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $42, %eax
popq %rbp
ret
Leh_func_end1:
如您所见,您的前提是有缺陷的。两个版本产生几乎相同的机器代码。
三十年来,人们一直在为 C/C++ 开发优化编译器。您可以假设他们已经想到了任何常见的用例,并尽其所能确保任何常见的代码模式都能生成最佳代码。永远不要改变你的编码风格来提高性能,除非你掌握了能够明确证明它存在差异的分析结果。太多此类“优化”不仅使代码更难阅读,而且实际上使性能更差。
编辑
这是与更大类型的类似比较。在这里,两种方法都返回以下struct:
struct Bar
{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int d;
};
这段代码:
void Foo(Bar& rc) {
rc.a = 1;
rc.b = 2;
rc.c = 3;
rc.d = 4;
}
产生这个输出:
__Z3FooR3Bar:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $1, (%rdi)
movl $2, 4(%rdi)
movl $3, 8(%rdi)
movl $4, 12(%rdi)
popq %rbp
ret
Leh_func_end1:
另一方面,这个按值返回的版本:
Bar Foo() {
Bar rc;
rc.a = 1;
rc.a = 2;
rc.a = 3;
rc.a = 4;
return rc;
}
最终产生更少机器代码指令:
__Z3Foov:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $4, %eax
xorl %edx, %edx
popq %rbp
ret
Leh_func_end1:
如果您想自己在 g++ 中进行这些比较,请使用 g++ -S -O3。其他编译器将具有类似的生成程序集的方法。