我是否应该避免在循环中的常数之间进行操作



我想知道在C 中是否存在某种优化或缓存,可以防止常数之间的相同数学操作重复,尤其是在循环中,从而降低了应用程序性能。例如:

for (int i = 0; i <= 100; i ++)
    std::cout << i << "meters / s:" << "=" << i * (3600/1000) << "Km / h" << endl;

上面的示例显然是虚构的,但这只是为了说明情况。它可能是一百万倍的循环,其中数百个涉及重复常数的计算。

然后我问:

  1. "(3600/1000("计算会在循环的100次上重复运行吗?
  2. 以这种方式,为了避免性能的损失,我应该在循环之前将该计算存储在常数变量中,然后通过该变量更改计算?
  3. 或不必担心它,因为C 给出了一种自动优化这些情况以避免绩效损失的方法吗?
  4. ,即使我更改为常数为" 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;
}

对于其他更复杂的对象,也许仅在需要立即需要结果的情况下运行计算,或者预先计算和存储结果以供以后使用。

最新更新