【问题标题】:Copy value into consts for optimization将值复制到 const 中以进行优化
【发布时间】:2013-04-29 12:53:40
【问题描述】:

假设您的第一个目标是执行速度,然后是代码清洁度,最后是资源使用率。

如果在算法的某个点,一个变量(例如一个双精度数)不会再发生变化(但您仍会多次读取它),您会将其复制为一个常量值吗?

【问题讨论】:

  • 很有可能编译器会检测到您的变量不会再被更改并优化(如果可以的话)作为这个观察的结果。现在,如果它使代码更清晰,请继续。但是您可能不应该太担心这种“优化”。
  • 我认为,Herb Sutter 在这里准确描述了这个问题:Complex initialization for a const variable
  • @EvgenyKluev:这是一个很好的提示。你为什么不把它作为一个答案?我很乐意对此表示赞同。
  • @EvgenyKluev:即使没有 lambda,我也经常使用 static 函数来进行初始化......请注意,我在 Sutter 的帖子中没有看到任何关于性能的声明。

标签: c++ algorithm variables optimization constants


【解决方案1】:

如果你想让你的代码更清晰,无论如何,将你的值复制到const double const_value = calculated_value;,但是编译器非常擅长跟踪依赖关系,而且这不太可能(假设你使用的是现代的、相当称职的编译器)因为你这样做,代码会更快或“更好”。编译器很有可能会因为您需要第二个变量这一事实而接受您的话,从而制作副本,并因此使代码变慢。

与往常一样,如果性能对您的应用程序很重要,请为您的特定代码制定“前后”比较基准,因为在 Internet 上阅读页面或在 SO 上询问与对代码进行基准测试不同。

【讨论】:

    【解决方案2】:

    只是将非常量变量复制到一个常量中并不能使代码更清晰,因为你有两个变量而不是一个变量。更有趣的是将非常数移出范围。这样,我们只有变量可见的常量版本,编译器可以防止我们错误地改变它的值。

    Herb Sutter 描述了如何使用 C++11 lambda 实现此目的:Complex initialization for a const variable

    const int i = [&]{
      int i = some_default_value;
    
      if(someConditionIstrue)
      {
        Do some operations and calculate the value of i;
        i = some calculated value;
      }
    
      return i;
    } ();
    

    (我不解释执行速度目标,因为它已经由 Mats Petersson 完成)。

    【讨论】:

    • 个人希望这个成语不要成语,太垃圾了。给 lambda 起个名字,然后我们就开始讨论了。
    • 我认为 Mats Petersson 的回答与问题更相关,但是 lambda 的这种用法很好,不幸的是也有点不灵活:想象一下这些操作也直接带来了第二个初始化值 j(对于另一个变量,假设我们正在计算一个 sincos),你将无法返回它进行赋值。
    • @DarioP:初始化第二个/第三个...变量,这个 lambda 可以返回一对、一个元组或一个结构。但这会不太方便。
    【解决方案3】:

    为了更好的代码可读性,您可以在变量不再更改的位置创建对变量的 const 引用,然后从该点开始使用 const 引用。

    double value_init;
    // Some code that generates value_init...
    const double& value = value_init;
    // Use value from now on in your algorithm
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 2022-01-16
      • 2010-10-25
      • 2012-05-31
      • 1970-01-01
      • 2014-08-20
      • 2018-07-11
      相关资源
      最近更新 更多