通过指针访问值与存储为临时值的效率

201*_*ker 5 c c++

如果有一个函数将指针struct作为参数,并且函数有一个循环,在每次迭代时访问一个成员,如:

int function_a(struct b *b)
{
    // ... do something then
    for(int i = 0; i < 500; ++i){
        b->c->d[i] = value();
    }
}
Run Code Online (Sandbox Code Playgroud)

它是否会每次检索c指向的位置和d指向内存?

现在考虑以下情况:

int function_a(struct b *b)
{
    // ... do something then
    float *f = b->c->d;
    for(int i = 0; i < 500; ++i){
        f[i] = value();
    }
}
Run Code Online (Sandbox Code Playgroud)

会更快吗?

Mat*_* M. 7

我敦促你注意托马斯马修斯关于剖析的建议,但要回答你的问题:这取决于你.

这种特殊的转换也称为代码提升,它包括移动代码而没有副作用,并且在循环外的每次调用时具有相同的结果.如上所述,只有在编译器可以证明:

  • 没有副作用
  • 在每次调用时计算相同的结果

在这两种情况下,这基本上意味着编译器应该可以访问两者的完整代码(参见定义):

  • 表达本身,证明没有副作用
  • 任何可能改变表达式的东西,以证明每次计算相同的结果

因此,它实际上不太可能执行优化,除非所有身体循环的代码都包含在头文件中(因此可以内联),因为任何不透明的函数都可以b->c通过邪恶的全局变量隐藏(例如)修改.

在你的例子中,没有任何证据证明value()不会改变b->c......所以不,编译器提升代码是错误的,除非它能够访问定义value()并且可以排除这种可能性.