首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >while(--i);和while(i) --i;之间有什么区别?

问while(--i);和while(i) --i;之间有什么区别?
EN

Stack Overflow用户
提问于 2018-11-20 17:15:58
回答 1查看 228关注 0票数 0

我第一次提交61.Rotate List只用了16毫秒,我对此并不满意。所以我更改了代码的这一部分

代码语言:javascript
复制
k += 1;
while (--k) {
    p = p->next;
}

至

代码语言:javascript
复制
while (k) {
    p = p->next;
    --k;
}

然后魔法就发生了。运行时间减少到8毫秒。

那么它们之间的区别是什么呢?为什么运行时差距如此之大?

EN

回答 1

Stack Overflow用户

发布于 2018-11-20 18:41:15

这可能只是一个编译器怪癖或基准测试错误。在所有情况下产生相同结果的代码段理论上应该编译成相同的程序集。通常,如果代码的某些部分被混淆(例如,在不同的翻译单元中),或者如果代码段足够复杂,优化器看不到等价性,编译器就无法优化。

在这种情况下,应该没有问题。事实上,GCC将这些片段编译成了同一个程序集。

代码语言:javascript
复制
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;
}

程序集输出为

代码语言:javascript
复制
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中查看它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53389693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档