我找到了一些像这样"优化"的代码:
void somefunc(SomeStruct param){
float x = param.x; // param.x and x are both floats. supposedly this makes it faster access
float y = param.y;
float z = param.z;
}
Run Code Online (Sandbox Code Playgroud)
并且评论说它会使变量访问速度更快,但我一直认为结构元素访问速度和它毕竟不是结构一样快.
有人能清除我的头脑吗?
Cat*_*lus 14
经验法则:它并不慢,除非探查者说它是.让编译器担心微观优化(他们对他们非常聪明;毕竟,他们已经做了多年)并专注于更大的图景.
小智 12
通常的优化规则(Michael A. Jackson)适用:1.不要这样做.2.(仅限专家:)不要这样做.
话虽如此,让我们假设它是最内层的循环,占用了性能关键型应用程序的80%的时间.即便如此,我怀疑你会看到任何不同.让我们使用这段代码:
struct Xyz {
float x, y, z;
};
float f(Xyz param){
return param.x + param.y + param.z;
}
float g(Xyz param){
float x = param.x;
float y = param.y;
float z = param.z;
return x + y + z;
}
Run Code Online (Sandbox Code Playgroud)
通过LLVM运行它显示:只有没有优化,两者按预期运行(g将结构成员复制到本地,然后对这些进行求和; f对从param直接获取的值求和).使用标准优化级别,两者都会产生相同的代码(提取值一次,然后对它们求和).
对于简短的代码,这种"优化"实际上是有害的,因为它不必要地复制浮动.对于在几个地方使用成员的较长代码,如果你主动告诉你的编译器是愚蠢的,那么它可能会有点帮助.使用65(而不是2)添加成员/本地的快速测试证实了这一点:没有优化,f重复加载结构成员,同时g重用已经提取的本地成员.优化版本再次相同,并且仅提取成员一次.(令人惊讶的是,即使启用LTO,也没有强度降低将增加转换为乘法,但这只表明所使用的LLVM版本无论如何都没有过于激烈地优化 - 所以它应该在其他编译器中也能正常工作.)
所以,最重要的是:除非你知道你的代码必须由编译器编译,这些编译器非常愚蠢和/或古老,以至于它不会优化任何东西,你现在已经证明了编译器会使两种方式等效并且可以因此,以表演的名义废除了这种可读性和酿造性犯罪.(如有必要,请为您的特定编译器重复实验.)
| 归档时间: |
|
| 查看次数: |
5035 次 |
| 最近记录: |