https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86023

            Bug ID: 86023
           Summary: Fake triviality test for internal purposes
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: glisse at gcc dot gnu.org
  Target Milestone: ---

While we cannot make std::pair or std::tuple trivial for now for ABI reasons,
it should still be safe to use memcpy-type optimizations for them when it is
safe for each member. We probably don't want to lie to the user in is_trivial
or is_trivially_copyable (?), but we could at least introduce an internal
version of those traits, specialized for a few types like pair/tuple, and use
them so _GLIBCXX_MOVE_BACKWARD3 would use memmove on std::pair<int,int> for
instance.

According to some benchmark, this might (they weren't exactly testing this)
change the average performance of insert/erase in
boost::flat_map<,,std::vector<>> by a factor of 2. Of course, it won't affect
the default flat_map, which uses boost's vector and traits, so it isn't a real
solution, just a small band-aid.

The exact traits to specialize depend on PR 68350.

#include <vector>
#include <utility>
#ifdef FAST
struct A {
  int first,second;
  A(int a,int b):first(a),second(b){}
  A()=default;
};
#else
typedef std::pair<int,int> A;
#endif
typedef std::vector<A> V;

int main(int argc,char**){
  V v;
  for(int i=0;i<100000;++i){
    v.insert(v.begin(),{i,i});
  }
  return v[argc].second;
}

At -O3, I get 3.41s for std::pair, 1.00s for the struct, and an intermediate
1.99s for the struct minus the default constructor.

Reply via email to