for(int i = 0; i < my_function(MY_CONSTANT); ++i){
//code using i
}
在这个例子中,每次迭代都会评估my_function(MY_CONSTANT)
,还是会自动存储?这取决于使用的优化标志吗?
答案 0 :(得分:10)
每次调用函数就好像一样。
但是,如果编译器每次都能证明函数结果是相同的,那么它可以在“as”规则下进行优化。
E.g。这通常发生在调用.end()
标准容器时。
一般建议:如果对是否微观优化一段代码存有疑问,
换句话说,根据代码的清晰度决定是否使用变量,而不是基于想象的性能。
答案 1 :(得分:3)
每次迭代都会对其进行评估。您可以通过执行类似
的操作来节省额外的计算时间const int stop = my_function(MY_CONSTANT);
for(int i = 0; i < stop; ++i){
//code using i
}
答案 2 :(得分:2)
as-if rule
下的现代优化编译器可能能够在您comment here中概述的情况下优化函数调用。 as-if rule
表示符合标准的编译器只模拟可观察行为,我们可以通过转到草案C ++标准部分1.9
程序执行来看到这一点,其中说:
[...]相反,需要符合实现来模拟(仅) 抽象机器的可观察行为,如下所述.5
因此,如果您使用常量表达式并且my_function
没有可观察到的副作用,则可以对其进行优化。我们可以组合一个简单的测试( see it live on godbolt ):
#include <stdio.h>
#define blah 10
int func( int x )
{
return x + 20 ;
}
void withConstant( int y )
{
for(int i = 0; i < func(blah); i++)
{
printf("%d ", i ) ;
}
}
void withoutConstant(int y)
{
for(int i = 0; i < func(i+y); i++)
{
printf("%d ", i ) ;
}
}
在withConstant
的情况下,我们可以看到它优化了计算:
cmpl $30, %ebx #, i
甚至在withoutConstant
的情况下,它会内联计算而不是执行函数调用:
leal 0(%rbp,%rbx), %eax #, D.2605
答案 3 :(得分:1)
如果my_function
被声明为constexpr且参数实际上是常量,则在编译时计算该值,从而实现&#34; as-if&#34;和#34;顺序一致,没有数据竞争&#34;规则。
constexpr my_function(const int c);
如果你的函数有副作用,它会阻止编译器将其移出for-loop
,因为它不能满足&#34; as-if&#34;规则,除非编译器可以推断它的出路。
编译器可能内联my_function
,减少它就像它是循环的一部分一样,并且通过常量减少发现它实际上只是一个常量,事实上删除了调用并用常量替换它。
int my_function(const int c) {
return 17+c; // inline and constant reduced to the value.
}
所以你的问题的答案是......也许!