我第一次提交61.Rotate List只用了16毫秒,我对此并不满意。所以我更改了代码的这一部分
k += 1;
while (--k) {
p = p->next;
}至
while (k) {
p = p->next;
--k;
}然后魔法就发生了。运行时间减少到8毫秒。
那么它们之间的区别是什么呢?为什么运行时差距如此之大?
发布于 2018-11-20 18:41:15
这可能只是一个编译器怪癖或基准测试错误。在所有情况下产生相同结果的代码段理论上应该编译成相同的程序集。通常,如果代码的某些部分被混淆(例如,在不同的翻译单元中),或者如果代码段足够复杂,优化器看不到等价性,编译器就无法优化。
在这种情况下,应该没有问题。事实上,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中查看它。
https://stackoverflow.com/questions/53389693
复制相似问题