我一直在寻找交换两个数字的替代选项,并且遇到了链接 How to swap two numbers
在评论部分提到使用临时变量更好。以下是我从链接中复制的评论
如果我们从CPU指令的角度来看问题,使用tmp将优于所有上述3种方法,我已经在所有这4种方法中再次运行基准测试(包括第4次使用临时变量)。毫不奇怪,第四种方式胜过以上3种方法。原因是CPU如何将变量移入寄存器以及我们需要使用多少寄存器。
但我无法找到它是如何工作的线索。有人可以解释一下它在处理器级别的工作原理以及为什么临时变量更好(如果是)?
答案 0 :(得分:2)
在此级别上查看何种优化的唯一方法是编译和反汇编。事实证明,编译器已经非常擅长删除或重新解释代码以使其更快。
我使用MS C编译器编译了这段代码:
int main()
{
int a = 1;
int b = 2;
int c;
// Force use of the variables so they aren't optimized away
printf("a = %d, b = %d\n", a, b);
c = b;
b = a;
a = c;
// Force use again
printf("a = %d, b = %d\n", a, b);
return 0;
}
这是优化后的实际输出,为简洁起见编辑:
; 4 : int a = 1;
; 5 : int b = 2;
; 6 : int c;
; OPTIMISED AWAY
; 8 : printf("a = %d, b = %d\n", a, b);
push 2
push 1
push pointer_to_string_constant
call DWORD PTR __imp__printf
; 10 : c = b;
; 11 : b = a;
; 12 : a = c;
; OPTIMISED AWAY
; 14 : printf("a = %d, b = %d\n", a, b);
push 1
push 2
push pointer_to_string_constant
call DWORD PTR __imp__printf
; 16 : return 0;
xor eax, eax ; Just a faster way of saying "eax = 0;"
; 17 : }
ret 0
所以你看,在这种情况下,编译器决定不使用任何变量,只需将整数直接推送到堆栈(这与将参数传递给C中的函数相同)。
这个故事的寓意不是在微观优化时再次猜测编译器。
答案 1 :(得分:1)
感谢大家的宝贵意见。我编写了一个简单的程序并查看了汇编输出(它是一个用Xcode编译的C程序)。看起来XOR操作的成本是使用临时变量的两倍。附加了生成的汇编代码图像。当我使用临时变量时,每个操作(a = b& so)都需要两个指令。但是当我使用XOR时,每个操作(a ^ = b& so)需要4个指令。以下是我的程序供参考。屏幕截图仅包含main(除了返回0)
中的行的汇编代码#include <stdio.h>
int main(int argc, const char * argv[])
{
int a = 100;
int b = 200;
int c;
c = a;
a = b;
b = c;
return 0;
}
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a = 100;
int b = 200;
a ^= b;
b ^= a;
a ^= b;
return 0;
}
这些结果可能特定于MAC运行时和/或Xcode编译的方式。如果您认为我在此过程中遗漏了某些内容,请发表评论。
答案 2 :(得分:-1)
“无临时变量”解决方案除了赋值之外,每个语句都有算术或逻辑运算。 例如,
x = x + y;
y = x - y;
x = x - y;
临时变量解决方案只会有作业。
temp = a;
a = b;
b = temp;
因此临时变量解决方案在CPU方面显然会有更好的表现。
答案 3 :(得分:-1)
如果我们使用以下方法
x = x + y;
y = x - y;
x = x - y;
这些说明包括算术运算和分配。它需要更多的CPU周期才能完成交换。
如果使用临时变量来交换两个值,则不需要任何算术运算。它只是通过赋值来做到这一点。与上述解决方案相比,这需要更少的CPU周期。