我正在alloc.c
中阅读lcc的源代码:
if ((ap->next = freeblocks) != NULL) {
freeblocks = freeblocks->next;
ap = ap->next;
}
为什么不
if (freeblocks != NULL) {
ap->next = freeblocks;
freeblocks = freeblocks->next;
ap = ap->next;
}
后者会造成额外费用吗?
答案 0 :(得分:8)
您发布的代码段功能不同。
第一个将freeblocks
分配给ap->next
,如果不是NULL
,则继续执行其他两个陈述。
如果freeblocks为freeblocks
,那么您建议的第二个版本不会将ap->next
分配给NULL
,并且在这种情况下实际上什么都不做。这不一样。
您可以将提案更改为以下内容, 功能相同:
ap->next = freeblocks;
if (freeblocks != NULL) {
freeblocks = freeblocks->next;
ap = ap->next;
}
这避免了一些人认为不好的风格的分配条件。假设您在编译时表示执行速度或代码大小,则不太可能导致任何额外的“成本”。
答案 1 :(得分:1)
如果您修改了第二个示例,使其在功能上相同,请说
ap->next = freeblocks;
if (freeblocks != NULL) {
freeblocks = freblocks->next;
ap = ap->next;
}
当你担心速度时,我希望你对编译器进行优化......
然后你的速度更快的问题的答案是:可能不是。
答案 2 :(得分:0)
性能是优化编译器中设计的一个功能。
多年前,我回顾了一位出版商的书籍手稿,其中作者展示了他声称生成更快代码的各种编程技巧(如副作用分配)。
我在几个编译器上编译了他的版本并且表明他的技巧没有产生更快的代码,并且大多数导致代码更慢。
您应该始终编写最清晰的代码,让编译器为您进行优化。
if语句中的赋值是一种糟糕的编程习惯。使用=而不是==是一个常见错误。始终如一地避免副作用分配使这些错误更容易被发现。
你在翻译中的错误表明原始代码有多么不清楚。这种糟糕的代码通常来自汇编语言程序员。
您修改后的版本会直接翻译成类似的内容(我的伪汇编代码)
MOV freeblocks, next(R0)
TEST next(R0) ; Test for zero
JUMPNE TEST
虽然原文的字面翻译更像是:
MOV freeblocks, next(R0)
JUMPNE TEST
大多数系统测试零作为移动指令的一部分。理论上,原始版本是一个较短的指令。
但是,任何优化编译器都足够智能,可以删除冗余的TEST。
编写内容来编写编译器是浪费时间,精力和清晰度。