我尝试了三种方法在 C 中的两个值之间切换变量,代码位于:
void with_xor(int *value)
{
*value ^= VAL_ONE ^ VAL_TWO;
}
void with_conditional(int *value)
{
*value = (*value == VAL_ONE)? VAL_TWO : VAL_ONE;
}
void with_if(int *value)
{
if(VAL_ONE == *value)
{
*value = VAL_TWO;
}
else
{
*value = VAL_ONE;
}
}
我期待“xor”方法比其他两种方法快得多,但似乎情况并非如此。这是为什么?
以下是测试结果:
xor 0.052300
conditional 0.035738
if 0.034924
这是一个反汇编(编译时没有标志):
_with_xor:
0000000100000bd0 pushq %rbp
0000000100000bd1 movq %rsp,%rbp
0000000100000bd4 movq %rdi,0xf8(%rbp)
0000000100000bd8 movq 0xf8(%rbp),%rax
0000000100000bdc movl (%rax),%eax
0000000100000bde xorl $0x0f,%eax
0000000100000be1 movq 0xf8(%rbp),%rcx
0000000100000be5 movl %eax,(%rcx)
0000000100000be7 popq %rbp
0000000100000be8 ret
0000000100000be9 nopl 0x00000000(%rax)
_with_conditional:
0000000100000bf0 pushq %rbp
0000000100000bf1 movq %rsp,%rbp
0000000100000bf4 movq %rdi,0xf8(%rbp)
0000000100000bf8 movq 0xf8(%rbp),%rax
0000000100000bfc movl (%rax),%eax
0000000100000bfe cmpl $0x0a,%eax
0000000100000c01 jne 0x100000c0c
0000000100000c03 movl $0x00000005,0xf4(%rbp)
0000000100000c0a jmp 0x100000c13
0000000100000c0c movl $0x0000000a,0xf4(%rbp)
0000000100000c13 movq 0xf8(%rbp),%rax
0000000100000c17 movl 0xf4(%rbp),%ecx
0000000100000c1a movl %ecx,(%rax)
0000000100000c1c popq %rbp
0000000100000c1d ret
0000000100000c1e nop
_with_if:
0000000100000c20 pushq %rbp
0000000100000c21 movq %rsp,%rbp
0000000100000c24 movq %rdi,0xf8(%rbp)
0000000100000c28 movq 0xf8(%rbp),%rax
0000000100000c2c movl (%rax),%eax
0000000100000c2e cmpl $0x0a,%eax
0000000100000c31 jne 0x100000c3f
0000000100000c33 movq 0xf8(%rbp),%rax
0000000100000c37 movl $0x00000005,(%rax)
0000000100000c3d jmp 0x100000c49
0000000100000c3f movq 0xf8(%rbp),%rax
0000000100000c43 movl $0x0000000a,(%rax)
0000000100000c49 popq %rbp
0000000100000c4a ret
0000000100000c4b nopl 0x00(%rax,%rax)