在C语言中,如果if语句包含赋值语句,是否会更快?

Is it faster in C if the If-Statement contains Assignment-Statements?

本文关键字:赋值语句 是否 包含 语句 语言 如果 if      更新时间:2023-10-16

我正在阅读lcc的源代码,在alloc.c:

if ((ap->next = freeblocks) != NULL) {
   freeblocks = freeblocks->next;
   ap = ap->next;
}

为什么不

if (freeblocks != NULL) {
   ap->next = freeblocks;
   freeblocks = freeblocks->next;
   ap = ap->next;
}

后者会造成额外的费用吗?

您发布的代码片段在功能上不相同。

第一个语句将freeblocks赋给ap->next,如果不是NULL,则继续执行其他两个语句。

第二个,你建议的,如果freeblocks是NULL,不将freeblocks分配给ap->next,实际上在这种情况下什么也不做。这是不一样的。

您可以将您的提案更改为以下内容,其中在功能上等同于:

ap->next = freeblocks;
if (freeblocks != NULL) {
   freeblocks = freeblocks->next;
   ap = ap->next;
}

这避免了将赋值作为条件的一部分,有些人认为这是糟糕的风格。如果您指的是编译时的执行速度或代码大小,则不太可能导致任何额外的"成本"。

如果您将第二个示例固定为功能相同,则写入

ap->next = freeblocks;
if (freeblocks != NULL) {
    freeblocks = freblocks->next;
    ap = ap->next;
}

,因为你担心速度,我希望你有编译器优化…

那么你的"它是不是更快"问题的答案将是:可能不是。

性能是优化编译器中设计的函数。

几年前,我为一个出版商审阅了一本书的手稿,其中作者展示了各种各样的编程技巧(比如副作用赋值),他声称这些技巧可以产生更快的代码。

我在几个编译器上编译了他的版本,结果表明,他的技巧没有一个能产生更快的代码,大多数都导致了更慢的代码。

你应该总是写最清晰的代码,让编译器为你做优化。

if语句中的

赋值是不好的编程习惯。使用=代替==是一个常见的错误。始终避免副作用赋值使这些错误更容易被发现。

你的翻译错误显示了原始代码是多么的不清楚。这种糟糕的代码通常来自于使用汇编语言的程序员。

修改后的版本翻译成这样(我的伪汇编代码)

MOV  freeblocks, next(R0)
TEST next(R0)                      ; Test for zero
JUMPNE TEST

而原文的直译更像是:

MOV  freeblocks, next(R0)
JUMPNE TEST

大多数系统测试零作为移动指令的一部分。理论上说,原始版本比原始版本少了一条指令。

然而,任何优化编译器都会足够聪明地删除冗余的TEST。

通过编码来猜出编译器是浪费时间、精力和清晰度。