Before this patch, std::map's copy constructor and copy assignment operators
would have significantly different performance characteristics. This was
caused by tree::operator= using assign_multi even in the case of a
container with unique keys like std::map. Furthermore, upon investigation,
it appears that __assign_unique was actually slower in some cases than
insert(first, last), because we were not using a hint to insert in the
loop. This patch fixes that issue which provides a small additional speedup.
In the future, we could instead reintroduce a copy assignment operator in
tree and copy the whole tree without performing any comparison. This
isn't done in this patch because such a patch should ensure the copy
assignment and copy constructors for tree are consistent, which goes
beyond the targeted fix I'm trying to do here. See https://llvm.org/PR62571.
This patch also adds a benchmark for std::map copy assignment, which
highlights the performance inconsistency we had.
Benchmark Time CPU Iterations
(before) BM_ConstructorCopy_MapSize=1000000 60.2 ns 60.2 ns 11000000
(before) BM_CopyAssignment_MapSize=1000000 68.7 ns 68.7 ns 11000000
(before) BM_CopyAssignmentPrepopulated_MapSize=1000000 42.1 ns 42.1 ns 17000000
(after) BM_ConstructorCopy_MapSize=1000000 59.9 ns 59.9 ns 12000000
(after) BM_CopyAssignment_MapSize=1000000 59.9 ns 59.9 ns 12000000
(after) BM_CopyAssignmentPrepopulated_MapSize=1000000 40.7 ns 40.7 ns 18000000
rdar://89335215
Why regenerating the data?