tmp = a; a = b; b = tmp;那怎样不使用中间变量交换两个变量的值? 也许你看过这样的方法:
a ^= b; b ^= a; a ^= b;这是一个借助于位运算的小伎俩, 但一般在实际编程中是不推荐使用的, 原因在大多数人看来应该是降低了代码的可读性, 其实还有一个被忽视的地方. 在多数人的直觉中位运算绝对比普通的运算符要快, 不过刚才的例子是一个反例.
现在让我们来看一下上面两段代码对应的汇编代码, 这里使用
gcc
作为编译器. 首先是使用了中间变量的那几句:
movl -4(%ebp), %eax movl %eax, -12(%ebp) movl -8(%ebp), %eax movl %eax, -4(%ebp) movl -12(%ebp), %eax movl %eax, -8(%ebp)"
-4(%ebp)
"、"-8(%ebp)
"、"-12(%ebp)
"分别是变量a
、b
、tmp
在栈中的地址, 同时使用了寄存器"eax
". 可以看出, 上面的代码一共对内存进行了3次读操作和3次写操作.
再来看看使用位运算的汇编代码:
movl -8(%ebp), %eax xorl %eax, -4(%ebp) movl -4(%ebp), %eax xorl %eax, -8(%ebp) movl -8(%ebp), %eax xorl %eax, -4(%ebp)一次"
xorl
"异或操作包含一次读和一次写, 因此一共是6次读操作和3次写操作.
通过比较可以看出位运算在I/O速度上已经不占优势, 再比较一下两种代码所需的内存空间, 下面这段汇编是公共的代码.
pushl %ebp movl %esp, %ebp subl $16, %esp两种方法都在栈中分配了16个字节的空间, 因此在空间上的比较是一样的. 这样看来, 使用位运算交换两个变量的值真是装B者必备的好东西.
No comments:
Post a Comment