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.