我有一个对一段数据进行操作的函数(比方说,int
),我想通过传递对valule的引用来更改它。因此,我有函数:void myFunction(int *thing) { ... }
。当我使用它时,我称之为:myFunction(&anInt)
。
由于我的功能经常被调用(但是来自许多不同的地方),我担心它的性能。我将其重构为函数的原因是可测试性和代码重用。
编译器是否能够优化该功能,将其内联直接在我的anInt
变量上操作?
我希望你能按照它所要求的精神来接受这个问题(即我不会过早地担心优化,我对答案感到好奇)。同样,我不想把它变成一个宏。
答案 0 :(得分:18)
查明函数是否内联的一种方法是使用-Winline
gcc选项:
-Winline Warn if a function can not be inlined and it was declared as inline. Even with this option, the compiler will not warn about failures to inline functions declared in system headers. The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.
答案 1 :(得分:9)
#include <stdio.h>
void __inline__ inc(int *val)
{
++ *val;
}
int main()
{
int val;
scanf("%d", &val);
inc(&val);
printf("%d\n", val);
return 0;
}
在gcc -S -O3 test.c
之后,您将获得以下相关的asm:
...
call __isoc99_scanf
movl 12(%rsp), %esi
movl $.LC1, %edi
xorl %eax, %eax
addl $1, %esi
movl %esi, 12(%rsp)
call printf
...
正如您所看到的,没有必要成为asm专家才能看到inc()调用已转换为增量指令。
答案 2 :(得分:7)
这里有两个问题 - 代码可以进行优化吗?它当然可以,但“意志”取决于优化器所处的情绪。如果这对您来说非常重要,请编译代码并查看汇编语言输出。
此外,您似乎在混淆两个问题。内联函数有效地将其正文粘贴在呼叫站点上。你是否使用指针既不在这里,也不在那里。但你似乎在问编译器是否可以转换:
int x = 42;
int * p = & x;
* p = * p + 1;
到
x = x + 1;
这对于优化者来说要困难得多。
答案 3 :(得分:2)
参数是否为指针无关紧要。
但首先,如果编译器自动内联函数,必须静态。它必须包含在同一个编译单元中。注意:我们谈论的是C,而不是C ++。 C ++内联规则不同。
如果无法在同一个编译单元中使用该函数,请尝试全局优化(有关详细信息,请查看编译器文档)。
C99为您提供“内联”关键字,就像在C ++中一样。这将限制提升到编译单元。
以下是一些further information。
答案 4 :(得分:1)
它会(或至少可以)。有一些原因导致函数无法内联 - 例如当您尝试访问函数的指针(通过引用调用函数 - 您通过引用访问参数,这是正常的)。可能还有其他情况(静态变量?不确定)
尝试使用“extern inline”声明该函数 - 这可以防止编译器发出独立的主体。如果它无法内联函数,则会发出错误。
答案 5 :(得分:0)
如果您担心编译器生成次优代码并想要更改简单的值类型,请将您的函数声明为int myFunction(int)
并返回新值。
答案 6 :(得分:-1)
您使用的是什么编译器版本?有什么选择?在什么平台上?
所有这些问题都会影响答案。您确实需要编译代码并查看程序集。
答案 7 :(得分:-1)
这看起来像是一个过早优化的经典案例。您确实知道这里存在性能问题吗?一个值得浪费宝贵时间的人担心。我的意思是,真的知道?比如,你有测量吗?
本身并不是太糟糕,但如果你对大量的代码采取这种态度,你可以做出一些严重的破坏,浪费大量的开发和维护时间,没有充分的理由。