【问题标题】:What is the performance problem with std::pair assignment operator?std::pair 赋值运算符的性能问题是什么?
【发布时间】:2020-11-23 23:46:49
【问题描述】:

我看过Danila Kutenin — C++ STL best and worst performance features 的演讲(包括同一演讲的另一个版本),我已经阅读了blog,但我仍然不明白是什么阻碍了 std::pair 赋值运算符的优化。

godbolt link of the comparison with custom pair,此处内联代码:

struct MyPair {
    int a;
    int b;
};

// slower
void CopyPair(const std::vector<std::pair<int, int>>& a,
              std::vector<std::pair<int, int>>& b) {
    std::copy(a.begin(), a.end(), b.begin());
}

// faster
void SmartCopyPair(const std::vector<MyPair>& a,
                   std::vector<MyPair>& b) {
    std::copy(a.begin(), a.end(), b.begin());
}

【问题讨论】:

标签: c++ stl compiler-optimization


【解决方案1】:

这不是 C++ 的问题,而是您使用的 STL 实现的问题。

如果你写以下检查

    static_assert(std::is_trivially_copyable_v<MyPair>,"MyPair is not trivially copyable");
    static_assert(std::is_trivially_copyable_v<std::pair<int,int>>,"std pair is not trivially copyable");

您会注意到只有第二行无法编译。并非所有 STL 实现都属于这种情况,而仅适用于您编译的那个,可能还有其他一些实现。

std::is_trivially_copyable_v&lt;T&gt; 为真时,T 的向量的std::copy 可能在整个范围内优化为memcpy,而不是按元素调用副本。

【讨论】:

  • std::pair 的标准规范不允许它被简单地复制,除非我错过了什么。
  • @aschepler 根据 cpp 参考,似乎 std::pair 应该是可简单复制构造的,但没有关于复制分配的具体信息。它看起来对我来说是收缩的,如果类型允许,我看不出有任何理由强制禁用琐碎的复制分配。据我了解,自 C++98 以来,实现并没有太大变化,改变它是 ABI 中断。
  • 您是说这是基于 ABI 问题的实现选择(在哪个 stdlib 中?)。是否有任何标准库实现可以使复制分配变得微不足道?
  • @JeffGarrett MSCV 确实如此。虽然,他们可能只是在这一点上不遵循标准。他们偶尔会有偏差。
  • 嗯,显然 C++20 让这种方式更容易实现...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 2010-09-11
  • 2021-10-28
  • 1970-01-01
  • 2018-01-03
  • 2021-04-16
相关资源
最近更新 更多