【发布时间】:2019-04-15 20:26:18
【问题描述】:
我有一个类似下面的循环,它有一个不变量,这里scaleEveryValueByTwo 的值永远不会改变。 我可以依靠编译器找到这个不变量,而不是在每次迭代中检查条件(本质上是编译成与底部代码类似的东西)吗?
void loadValuesFromDisk(const bool scaleEveryValueByTwo)
{
std::vector<MyValueType> xs;
while(fileHasNewValues())
{
auto x = loadNextValue();
if (scaleEveryValueByTwo)
{
x *= 2;
}
xs.push_back(x);
}
}
我当然可以手动将其拆分为两个循环(见下文)或将缩放部分放在单独的函数中,但在许多情况下,这会使代码更长并且在我看来更难阅读(例如,如果我有3D 数据所有维度的嵌套循环我将复制所有三行循环标题和最多六行花括号)。
void loadValuesFromDisk(const bool scaleEveryValueByTwo)
{
std::vector<MyValueType> xs;
while(fileHasNewValues())
{
auto x = loadNextValue();
xs.push_back(x);
}
if (scaleEveryValueByTwo)
{
for(auto &x : xs)
{
x *= 2;
}
}
}
我主要感兴趣的是我是否可以依赖这个(或者更好的是,强制执行)这个优化,用于 gcc 或 MSVC 等常用编译器,而不是一些可能缺少大多数编译器事实上标准的优化的奇异编译器。
【问题讨论】:
-
很有可能。即使它没有,分支预测器也会快速学习它并且性能是一样的。
-
一般的经验法则是,编译器会做出所有你能想到的优化以及一堆你甚至没有想到的其他优化。
-
@NathanOliver 是正确的...编译器很可能会执行此优化如果这是一个好主意。在分析结果的上下文之外提出这类问题几乎可以肯定是过早的优化(即错误的问题)。