【发布时间】:2011-12-19 21:09:33
【问题描述】:
我猜你们都听说过“交换问题”; SO充满了关于它的问题。 不使用第三个变量的交换版本通常被认为更快,因为你少了一个变量。我想知道幕后发生了什么,并编写了以下两个程序:
int main () {
int a = 9;
int b = 5;
int swap;
swap = a;
a = b;
b = swap;
return 0;
}
以及没有第三个变量的版本:
int main () {
int a = 9;
int b = 5;
a ^= b;
b ^= a;
a ^= b;
return 0;
}
我使用 clang 生成了汇编代码,并为第一个版本(使用第三个变量)得到了这个:
...
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $0, %eax
movl $0, -4(%rbp)
movl $9, -8(%rbp)
movl $5, -12(%rbp)
movl -8(%rbp), %ecx
movl %ecx, -16(%rbp)
movl -12(%rbp), %ecx
movl %ecx, -8(%rbp)
movl -16(%rbp), %ecx
movl %ecx, -12(%rbp)
popq %rbp
ret
Leh_func_end0:
...
第二个版本(不使用第三个变量):
...
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $0, %eax
movl $0, -4(%rbp)
movl $9, -8(%rbp)
movl $5, -12(%rbp)
movl -12(%rbp), %ecx
movl -8(%rbp), %edx
xorl %ecx, %edx
movl %edx, -8(%rbp)
movl -8(%rbp), %ecx
movl -12(%rbp), %edx
xorl %ecx, %edx
movl %edx, -12(%rbp)
movl -12(%rbp), %ecx
movl -8(%rbp), %edx
xorl %ecx, %edx
movl %edx, -8(%rbp)
popq %rbp
ret
Leh_func_end0:
...
第二个更长,但我对汇编代码了解不多,所以我不知道这是否意味着它更慢,所以我想听听更了解它的人的意见。
以上哪个版本的变量交换速度更快,占用的内存更少?
【问题讨论】:
-
要找出哪个更快,为什么不对其进行基准测试?
-
我不知道如何测量内存使用量,而且我也对它背后的原因感兴趣。
-
看起来您编译时没有启用优化。那个程序集里有很多绒毛。
-
XOR 技巧可能在很久以前就已经更快了,但在现代 CPU 上却没有。只需使用一个临时变量并启用编译器优化。
-
试图判断编译器生成代码的速度而忽略优化是没有意义的