【问题标题】:Is it sensible optimization to check if an iterator has a value that we want to assign in C++检查迭代器是否具有我们要在 C++ 中分配的值是否明智的优化
【发布时间】:2019-09-14 16:13:00
【问题描述】:

有一个类似的问题16114572 但我这里更具体。

请回答第 3 行的问题:

void change_head(map<K, V>& m, V const& value) {
  auto head = m.begin();
  if (head->second != value)   // <--- Make sense?
    head->second = value;
}

比如说,我们对V 唯一了解的就是具有运算符!= 并且它是可复制。 但是,没有关于这些操作有多快的信息(copy!=)。

统一更新: 想象一下,我们正在建立一个图书馆。我们可能会假设相等会比复制更快,但我不确定!这种优化值得吗?

我的主要语言不是 C++,所以我只是想知道 C++ 世界的人在做什么。

【问题讨论】:

  • 但是,没有关于这些操作有多快的信息(复制和!=)。恕我直言,这是让这个问题难以回答的重要事实。对于原始类型,我会阻止比较并只分配值。阻止额外的分支通常会使分配变得更加复杂。对于非原始类型,它取决于复制成本和operator!=()。另一个问题是总体上是否值得优化单个分配。如果它是在循环中发生数百万次的事情......
  • 与您的问题无关,但是,如果您的意图是更改地图内容,您确定 const 对地图的引用吗?
  • 您要求对此代码的性能发表评论,但需要注意的是,我们不能对代码部分的性能做出任何假设。这个问题无法回答。
  • @prog-fh 谢谢,我已经删除了“const”

标签: c++ iterator operator-overloading copy-constructor equality


【解决方案1】:

是否合理优化

除非您可以衡量改进,否则这根本不是优化。它只是看起来很优化的货物狂热垃圾,比如速度更快的条纹。

(这不是侮辱 - 每个人都容易希望他们的代码快速,这通常会导致您编写看起来快的代码。解决方案是学会不要相信外表,而是养成正确分析代码的习惯。

但是,没有关于这些操作有多快的信息

除非有理由,否则不要编写额外的代码。

在这里,您没有任何理由相信较长的版本更正确或性能更好。我们唯一确定的是,我们增加了一些认知开销(需要阅读更多代码)和测试和分支(或条件移动)。

我们应该被要求证明编写越来越复杂的代码是合理的——这在这里我们不能。 IME 这很可能更糟比原始版本,因为 test-and-branch 溢出分支预测器,或者因为负载依赖性,或者因为额外的指令缓存压力。 p>


编辑:

UPD:想象一下,我们正在构建一个库

如果您希望存储的内容可能复制起来非常昂贵,但比较起来却很便宜,那么为值类型提供一个可选的包装器会更容易,而不是将其放入容器中:

template <typename T>
class CheapCompareExpensiveCopy
{
    T value_;
public:
    using SelfT = CheapCompareExpensiveCopy<T>;

    // usual constructors etc.
    SelfT& operator=(SelfT const &other)
    {
      if (other.value_ != value_) {
        value_ = other.value_;
      }
      return *this;
    }
};

【讨论】:

    猜你喜欢
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 2017-04-21
    • 2023-03-10
    • 2021-01-13
    • 2013-03-27
    • 2011-12-17
    相关资源
    最近更新 更多