我第一次提交61.Rotate List的时间为16毫秒,对此我感到不满意。所以我更改了这部分代码
k += 1;
while (--k) {
p = p->next;
}
到
while (k) {
p = p->next;
--k;
}
然后魔术发生了。运行时间减少到8毫秒。
那么它们之间有什么区别?为什么运行时差距如此之大?
答案 0 :(得分:3)
这可能只是编译器怪癖或基准测试错误。在所有情况下都能产生相同结果的代码段理论上应编译为同一程序集。通常,如果混淆了部分代码(例如,使用不同的翻译单元),或者如果代码段太复杂以至于优化器看不到等效项,则编译器将无法优化。
在这种情况下,应该没有问题。确实,GCC将这些段编译为同一程序集。
struct P {
P* next;
};
P* func1(unsigned int k, P* p) {
k += 1;
while (--k) {
p = p->next;
}
return p;
}
P* func2(unsigned int k, P* p) {
while (k) {
p = p->next;
--k;
}
return p;
}
程序集输出为
func1(unsigned int, P*):
movq %rsi, %rax
testl %edi, %edi
je .L2
.L3:
movq (%rax), %rax
subl $1, %edi
jne .L3
.L2:
ret
func2(unsigned int, P*):
movq %rsi, %rax
testl %edi, %edi
je .L10
.L11:
movq (%rax), %rax
subl $1, %edi
jne .L11
.L10:
ret
除了跳转标签,这些功能的组件是相同的。您可以在Godbolt here中查看它。