Open Quuxplusone opened 8 months ago
That sounds great.
How was it not already trivially copyable...
@vinniefalco because we use character traits
My only reservation with this PR is that this would result in all bytes being copied (regardless of size()
... @pdimov what do you think?
This has always been the tradeoff. I prefer triviality, and memcpy with a constant N is pretty fast these days, but if we envisage static strings being often used with something like N=16384...
Although on second thought, if N is 16384, then one would expect size() to be somewhere in the thousands on average, so copying will be expensive anyway.
I'm pretty sure we touched this during the formal review, but I don't remember what I argued for. :-) Triviality, probably. It just makes more sense, incl. aesthetically.
My only reservation with this PR is that this would result in all bytes being copied (regardless of
size()
)...This has always been the tradeoff. I prefer triviality, and memcpy with a constant N is pretty fast these days, but if we envisage static strings being often used with something like N=16384...
Ah, I see, that's the same issue raised in folly::small_vector
in https://github.com/facebook/folly/pull/1934#issuecomment-1954812655 . As I summarized there: we're comparing "trivial copy (i.e. memcpy) size() elements" (saves cache lines, can't fully unroll) against "memcpy capacity() elements" (costs cache lines, can fully unroll).
Folly's answer to the tradeoff was essentially equivalent to:
static_string(const static_string&)
requires (sizeof(*this) <= hardware_constructive_interference_size / 2)
= default;
constexpr static_string(const static_string& rhs) noexcept
{ assign(rhs); }
I don't know if you care to do something similar here, or what, but anyway, this is now a tradeoff discussion above my pay grade. :)
They have the advantage of having the thing deployed at scale, so they can measure.
I suppose we can make it trivial for N <= 64, or something like that. Conditional triviality is a pain in C++11 though.
(hardware_interference_size is better left unused because it can lead to nice ABI issues as the warning says.)
It's not clear to me why this wasn't true from the very beginning, and
git grep trivial
doesn't enlighten me.=default
requires at least C++11, but then so doesnoexcept
, so that must not be a concern. Notice that at this point this is an ABI break forstatic_string
; I don't know if you care about ABI breaks. If you do care about ABI breaks, but would like to mark the type as trivially relocatable (without an ABI break) on compilers that support P1144, let me know and I'll open a separate PR for that.