4

I have watched the talk Danila Kutenin — C++ STL best and worst performance features (including one other version of the same talk), I have read the blog, but I still do not understand what is preventing optimization of std::pair assignment operator.

godbolt link of the comparison with custom pair, code inlined here:

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());
}
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • Not a dupe but somewhat related: [What is the purpose of having an empty `pair` base class?](https://stackoverflow.com/questions/64931324/what-is-the-purpose-of-having-an-empty-pair-base-class) – Ted Lyngmo Nov 24 '20 at 00:31
  • Could you summarize what you expect / what you are demonstrating? I'm not inclined to follow external links to get the gist of a SO question. – JaMiT Nov 24 '20 at 01:53

1 Answers1

3

This is not an issue of C++ but rather of the STL implementation you use.

If you write following checks

    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");

You'll notice that only the second line fails to compile. This isn't the case for all STL implementations but only the one you compile on and possibly some other.

When std::is_trivially_copyable_v<T> is true then std::copy of vector of T is probably implementation level optimized to memcpy on the whole range instead of calling copy per element.

ALX23z
  • 4,456
  • 1
  • 11
  • 18
  • 1
    The Standard's specification of `std::pair` doesn't allow it to ever be trivially copyable, unless I've missed something. – aschepler Nov 24 '20 at 09:40
  • @aschepler according to cpp reference it seems that `std::pair` is supposed to be trivially copy constructible but no concrete info about copy assignment. It looks contracting to me and I don't see any reason why forcefully disable trivial copy assignment if the type allows it. From my understanding the implementation simply didn't change much since C++98 and changing it is an ABI break. – ALX23z Nov 24 '20 at 09:48
  • You're saying it's an implementation choice based on ABI concerns (in which stdlib?). Is there any standard library implementation that manages to make copy assignment trivial? – Jeff Garrett Nov 27 '20 at 00:28
  • @JeffGarrett MSCV does. Although, it could that they just don't follow standart on this point. They occasionally have deviations. – ALX23z Nov 27 '20 at 07:47
  • Hmm, apparently C++20 makes this *way* easier to accomplish... – Jeff Garrett Nov 27 '20 at 08:47