下面的代码会被优化为一个函数调用吗

Would the following code be optimized to one function call?

本文关键字:一个 函数调用 代码 优化      更新时间:2023-10-16

我几乎没有编译器专业知识,我想知道以下代码片段是否会被相对较新的(VS2008+/GCC 4.3+)编译器自动优化:

Object objectPtr = getPtrSomehow();
if (objectPtr->getValue() == something1)       // call 1
dosomething1;
else if (objectPtr->getValue() == something2)  // call N (there are a few more)
dosomething2;
return;

其中getValue()只是返回一个成员变量,该变量是枚举中的一个。(呼叫没有明显影响)

我的编码风格是在"switch"之前进行一次调用,并保存值以将其与每个somethingX进行比较,但我想知道这对于今天的编译器来说是否是一个没有意义的问题。

我自己也不确定该用谷歌搜索什么来找到答案。

谢谢你,

AK

这是没有实际意义的,尤其是在方法是可变的情况下。

如果未声明getValueconst,则无法优化该调用,因为后续调用可能返回不同的值。

如果它被声明为const,它会更容易,但编译器优化调用也很简单。它需要访问实现,以确保调用不会产生副作用。即使标记为const(修改并返回全局),它也有可能返回不同的值。

除非编译器能够在编译该段代码时检查getValue()的定义,否则它不能省略第二次调用,因为它不知道该调用是否具有可观察的效果,也不知道第二次是否返回相同的值。

即使它看到了定义,它也很可能(这是我对一些编译器内部的粗略猜测)不会特意检查这一点。唯一的可能性是实现被琐碎的内联两次,然后被公共子表达式消除捕获EDIT:由于定义在标头中,而且非常小,所以这(内联和随后的CSE)很可能会出错。不过,如果您想确定,请检查g++ -O2 -S或编译器的等效输出。

总之,您不应该期望优化发生。再说一遍,getValue可能相当便宜,所以不太可能值得手动优化。与几个机器循环相比,额外的一行是什么?在大多数情况下不多。如果您正在编写代码,那么您不应该询问,而应该检查它(反汇编/分析)。

正如其他答案所指出的,编译器通常无法消除第二个调用,因为可能会有副作用。

然而,有些编译器有一种方法可以告诉编译器该函数没有副作用,并且允许进行这种优化。在GCC中,函数可以声明为pure。例如:

int square(int) __attribute__((pure));

表示,该函数"除了返回值之外没有任何效果,并且返回值仅取决于参数和/或全局变量。">

您写道:

我的编码风格是在"切换"之前进行一次调用,并保存值以进行比较它反对X的每一个,但我想知道这是否是一个没有意义的观点使用今天的编译器。

是的,这是一个没有意义的问题。编译器所做的就是它的业务。你将忙于编写可维护的代码,而不必试图对一个比我们任何人都希望的工作都要好得多的软件进行微观管理

专注于编写可维护的代码,并相信编译器能够完成任务。如果你以后发现你的代码太慢,那么你可以担心优化。

记住这句谚语:

过早的优化是万恶之源。

相关文章: