我想知道在C 中是否存在某种优化或缓存,可以防止常数之间的相同数学操作重复,尤其是在循环中,从而降低了应用程序性能。例如:
for (int i = 0; i <= 100; i ++)
std::cout << i << "meters / s:" << "=" << i * (3600/1000) << "Km / h" << endl;
上面的示例显然是虚构的,但这只是为了说明情况。它可能是一百万倍的循环,其中数百个涉及重复常数的计算。
然后我问:
- "(3600/1000("计算会在循环的100次上重复运行吗?
- 以这种方式,为了避免性能的损失,我应该在循环之前将该计算存储在常数变量中,然后通过该变量更改计算?
- 或不必担心它,因为C 给出了一种自动优化这些情况以避免绩效损失的方法吗?
- ,即使我更改为常数为" A"的3600,而对于常数为" b"的1000,也就是说,即使" A"one_answers" B"是常数,而不是3600/1000,我有" A/B"然而,该操作是反复计算的100次还是有任何优化?
我知道这个问题是相关的,因为它涉及应采用的编程样式。
这读起来像是评论,但与您担心的答案很重要。
编译器比您聪明。
试图编写快速代码时,这是一个非常好的经验法则。
写可读的代码,您的编译器很可能会完成其余的。
不必担心您显示的片段。恒定折叠是一种基本优化技术。循环展开也是如此(尤其是固定数量的迭代(。
您唯一需要的是一个编译器标志来激活优化:-O3(或其他(在clang/gcc上,/o3 for MSVC。
,即使代码可以很好地工作,我建议给您的魔术常数一个名称以提高可读性:
constexpr static const auto SECONDS_IN_HOUR = 3600;
constexpr static const auto METERS_IN_KILOMETER = 1000;
constexpr static const auto FACTOR_KILOMETER_PER_HOUR_TO_METERS_PER_SECOND = static_cast<double>(SECONDS_IN_HOUR) / static_cast<double>(METERS_IN_KILOMETER);
由于这是constexpr,应在编译时计算这些,因此不会导致运行时开销。这甚至可以在未启用优化的情况下起作用。
请注意,从C 17中,这些常数隐含着内联。因此,如果您使用旧编译器,则可能需要一些更改。
某些CPU将在自己的缓存中保留重复的计算。
我的建议是将结果放在那里,因此它永远不必这样做。同样始终使用牙套,以防稍后添加更复杂的结构。
for(int i = 0; i <= 100; i ++) {
std::cout << i << "meters / s:" << "=" << i * 3.6 << "Km / h" << endl;
}
对于其他更复杂的对象,也许仅在需要立即需要结果的情况下运行计算,或者预先计算和存储结果以供以后使用。