Commit 4c5877d
authored
[libc++] Optimize map::insert_or_assign (llvm#155816)
`__emplace_unique` uses `__find_equal`, which can be significantly
faster than `lower_bound`. As a nice side-effect, this also changes the
implementation to the "naive" implementation of trying `insert` first,
and if that fails assign instead. This also matches the
`insert_or_assign` overloads with a hint.
```
Zen 2:
--------------------------------------------------------------------------------------------------------
Benchmark old new
--------------------------------------------------------------------------------------------------------
std::map<int, int>::insert_or_assign(key, value) (already present)/0 1.62 ns 1.53 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/32 5.78 ns 5.99 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/1024 21.5 ns 15.4 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/8192 26.2 ns 20.5 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/0 22.5 ns 21.1 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/32 42.9 ns 28.4 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/1024 118 ns 92.0 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/8192 227 ns 173 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/0 13.2 ns 18.9 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/32 65.6 ns 39.0 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/1024 127 ns 64.4 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/8192 134 ns 71.4 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/0 45.6 ns 37.3 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/32 142 ns 93.3 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/1024 288 ns 147 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/8192 368 ns 182 ns
Apple M4:
--------------------------------------------------------------------------------------------------------
Benchmark old new
--------------------------------------------------------------------------------------------------------
std::map<int, int>::insert_or_assign(key, value) (already present)/0 0.784 ns 0.740 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/32 2.52 ns 1.77 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/1024 8.72 ns 4.06 ns
std::map<int, int>::insert_or_assign(key, value) (already present)/8192 10.6 ns 3.98 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/0 17.3 ns 17.2 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/32 22.5 ns 19.3 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/1024 56.8 ns 33.5 ns
std::map<int, int>::insert_or_assign(key, value) (new value)/8192 88.2 ns 41.0 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/0 16.6 ns 11.8 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/32 13.7 ns 30.7 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/1024 46.7 ns 49.1 ns
std::map<std::string, int>::insert_or_assign(key, value) (already present)/8192 41.9 ns 76.9 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/0 40.0 ns 40.5 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/32 38.9 ns 40.0 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/1024 84.9 ns 96.9 ns
std::map<std::string, int>::insert_or_assign(key, value) (new value)/8192 166 ns 149 ns
```1 parent c9d7d10 commit 4c5877d
File tree
3 files changed
+54
-12
lines changed- libcxx
- docs/ReleaseNotes
- include
- test/benchmarks/containers/associative
3 files changed
+54
-12
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1144 | 1144 | | |
1145 | 1145 | | |
1146 | 1146 | | |
1147 | | - | |
1148 | | - | |
1149 | | - | |
1150 | | - | |
1151 | | - | |
1152 | | - | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
1153 | 1152 | | |
1154 | 1153 | | |
1155 | 1154 | | |
1156 | 1155 | | |
1157 | | - | |
1158 | | - | |
1159 | | - | |
1160 | | - | |
1161 | | - | |
1162 | | - | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
1163 | 1161 | | |
1164 | 1162 | | |
1165 | 1163 | | |
| |||
Lines changed: 43 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
259 | 259 | | |
260 | 260 | | |
261 | 261 | | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
262 | 305 | | |
263 | 306 | | |
264 | 307 | | |
| |||
0 commit comments