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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Please provide the testcase in a usable form, not just a link to an external
site (which uses its own custom benchmark macros). This is requested at
https://gcc.gnu.org/

The relevant code is:

#include <string>
#include <array>

auto make_bytes() {
  std::array<unsigned char, 1024 * 1024> result;
  for (int i = 0; i < result.size(); i++) {
    result[i] = i % 256;
  }
  return result;
}

auto raw_data = make_bytes();

static void BenchmarkAssign() {
  std::string target_data;
  target_data.assign(raw_data.begin(), raw_data.end());
}

This is not equivalent to the other forms of copying in the benchmark, because
string::assign has to handle possible aliasing. It's valid to do things like
str.assign(str.data()+1, str.data()+2).

The copy constructor doesn't have to deal with that case (the input can't
possibly alias the object under construction). The assignment operator form
also just uses the copy constructor followed by a cheap move. For the
resize+std::copy form there's a precondition on std::copy that the start of the
output range is not in the input range, which rules out the problematic forms
of aliasing.

Reply via email to