[libcxx-commits] [libcxx] [libc++] Tiny optimizations for is_permutation (PR #129565)
Imad Aldij via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Mar 24 11:55:05 PDT 2025
imdj wrote:
I tried to do some more experiments, this time also comparing `GCC 14.2.1` against `Clang 19.1.7`. I found that getting rid of the preemptive advancement of the iterator resulted in a significant improvement in performance and enabled better optimizations in both compilers.
Let me know what you think and if there are any further suggestions. Here are the results after the change:
<details>
<summary>GCC v14 results (Mean Time: -0.1017)</summary>
```
Benchmark Time CPU Time Old Time New CPU Old CPU New
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
std::is_permutation(vector<int>) (3leg) (common prefix)/8 +0.0698 +0.0700 6 6 6 6
std::is_permutation(vector<int>) (3leg) (common prefix)/1024 -0.0043 -0.0043 529 527 529 526
std::is_permutation(vector<int>) (3leg) (common prefix)/8192 -0.0013 -0.0011 4142 4136 4141 4136
std::is_permutation(deque<int>) (3leg) (common prefix)/8 -0.0706 -0.0706 21 20 21 20
std::is_permutation(deque<int>) (3leg) (common prefix)/1024 +0.0007 +0.0009 2480 2482 2479 2482
std::is_permutation(deque<int>) (3leg) (common prefix)/8192 +0.0147 +0.0147 19809 20101 19809 20100
std::is_permutation(list<int>) (3leg) (common prefix)/8 +0.0004 +0.0002 9 9 9 9
std::is_permutation(list<int>) (3leg) (common prefix)/1024 +0.0038 +0.0038 3848 3863 3848 3863
std::is_permutation(list<int>) (3leg) (common prefix)/8192 +0.0003 +0.0006 41776 41790 41766 41790
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/8 -0.0020 -0.0020 7 7 7 7
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/1024 -0.0017 -0.0019 632 631 632 630
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/8192 -0.0042 -0.0042 4981 4960 4981 4960
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/8 +0.0869 +0.0867 16 18 16 18
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/1024 +0.0004 +0.0006 1257 1258 1257 1258
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/8192 +0.0025 +0.0023 9979 10003 9979 10001
std::is_permutation(list<int>) (3leg, pred) (common prefix)/8 -0.0002 +0.0000 10 10 10 10
std::is_permutation(list<int>) (3leg, pred) (common prefix)/1024 +0.0006 +0.0004 4212 4215 4212 4214
std::is_permutation(list<int>) (3leg, pred) (common prefix)/8192 +0.0153 +0.0155 40564 41183 40556 41183
std::is_permutation(vector<int>) (4leg) (common prefix)/8 +0.0280 +0.0278 14 14 14 14
std::is_permutation(vector<int>) (4leg) (common prefix)/1024 +0.0006 +0.0009 842 842 842 842
std::is_permutation(vector<int>) (4leg) (common prefix)/8192 +0.0005 +0.0004 6605 6608 6605 6608
std::is_permutation(deque<int>) (4leg) (common prefix)/8 -0.2560 -0.2560 36 27 36 27
std::is_permutation(deque<int>) (4leg) (common prefix)/1024 -0.4996 -0.4996 2529 1266 2529 1266
std::is_permutation(deque<int>) (4leg) (common prefix)/8192 -0.5466 -0.5467 22048 9996 22048 9994
std::is_permutation(list<int>) (4leg) (common prefix)/8 +0.0004 +0.0004 13 13 13 13
std::is_permutation(list<int>) (4leg) (common prefix)/1024 +0.0199 +0.0197 3866 3943 3866 3942
std::is_permutation(list<int>) (4leg) (common prefix)/8192 +0.0060 +0.0060 40626 40872 40626 40872
rng::is_permutation(vector<int>) (4leg) (common prefix)/8 +0.1060 +0.1058 15 17 15 17
rng::is_permutation(vector<int>) (4leg) (common prefix)/1024 +0.0012 +0.0012 843 844 843 844
rng::is_permutation(vector<int>) (4leg) (common prefix)/8192 -0.0001 -0.0001 6608 6608 6608 6608
rng::is_permutation(deque<int>) (4leg) (common prefix)/8 -0.0317 -0.0315 37 36 37 36
rng::is_permutation(deque<int>) (4leg) (common prefix)/1024 -0.0008 -0.0010 2909 2907 2909 2906
rng::is_permutation(deque<int>) (4leg) (common prefix)/8192 -0.0015 -0.0013 23223 23188 23218 23188
rng::is_permutation(list<int>) (4leg) (common prefix)/8 -0.0002 -0.0002 14 14 14 14
rng::is_permutation(list<int>) (4leg) (common prefix)/1024 +0.0042 +0.0044 3839 3855 3838 3855
rng::is_permutation(list<int>) (4leg) (common prefix)/8192 +0.0156 +0.0154 40622 41256 40622 41247
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/8 -0.1135 -0.1133 11 10 11 10
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/1024 -0.0034 -0.0034 838 836 838 836
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/8192 -0.0011 -0.0011 6609 6602 6607 6600
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/8 +0.0381 +0.0381 33 34 33 34
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/1024 +0.3936 +0.3936 2084 2904 2083 2904
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/8192 +0.3959 +0.3959 16586 23152 16585 23152
std::is_permutation(list<int>) (4leg, pred) (common prefix)/8 +0.0003 +0.0001 12 12 12 12
std::is_permutation(list<int>) (4leg, pred) (common prefix)/1024 +0.0153 +0.0153 3844 3903 3844 3903
std::is_permutation(list<int>) (4leg, pred) (common prefix)/8192 -0.0056 -0.0056 41698 41465 41689 41455
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/8 -0.1110 -0.1110 11 10 11 10
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/1024 -0.0034 -0.0036 838 836 838 835
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/8192 -0.0112 -0.0110 6673 6598 6671 6598
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/8 +0.0533 +0.0531 33 35 33 35
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/1024 +0.3932 +0.3935 2084 2903 2083 2903
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/8192 +0.3957 +0.3955 16587 23151 16587 23146
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/8 -0.0006 -0.0004 12 12 12 12
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/1024 -0.0012 -0.0014 3885 3881 3885 3880
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/8192 -0.0027 -0.0024 41501 41391 41492 41391
std::is_permutation(vector<int>) (3leg) (shuffled)/8 -0.0077 -0.0077 95 95 95 95
std::is_permutation(vector<int>) (3leg) (shuffled)/1024 -0.0083 -0.0081 706015 700140 705871 700142
std::is_permutation(deque<int>) (3leg) (shuffled)/8 +0.0011 +0.0011 220 220 220 220
std::is_permutation(deque<int>) (3leg) (shuffled)/1024 +0.0007 +0.0009 2985438 2987624 2984818 2987613
std::is_permutation(list<int>) (3leg) (shuffled)/8 +0.0545 +0.0545 174 183 174 183
std::is_permutation(list<int>) (3leg) (shuffled)/1024 +0.0017 +0.0019 4568861 4576605 4567919 4576614
std::is_permutation(vector<int>) (3leg, pred) (shuffled)/8 +0.0112 +0.0112 135 136 135 136
std::is_permutation(vector<int>) (3leg, pred) (shuffled)/1024 +0.0199 +0.0197 1975693 2015043 1975696 2014617
std::is_permutation(deque<int>) (3leg, pred) (shuffled)/8 -0.8860 -0.8860 241 27 241 27
std::is_permutation(deque<int>) (3leg, pred) (shuffled)/1024 -0.9993 -0.9993 3197946 2232 3197952 2231
std::is_permutation(list<int>) (3leg, pred) (shuffled)/8 +0.0829 +0.0829 126 136 126 136
std::is_permutation(list<int>) (3leg, pred) (shuffled)/1024 +0.0008 +0.0008 4891431 4895407 4890419 4894382
std::is_permutation(vector<int>) (4leg) (shuffled)/8 +0.0351 +0.0351 96 100 96 100
std::is_permutation(vector<int>) (4leg) (shuffled)/1024 +0.0015 +0.0013 700257 701309 700253 701165
std::is_permutation(deque<int>) (4leg) (shuffled)/8 +0.0107 +0.0110 234 237 234 237
std::is_permutation(deque<int>) (4leg) (shuffled)/1024 +0.0006 +0.0004 3195212 3197090 3195197 3196420
std::is_permutation(list<int>) (4leg) (shuffled)/8 +0.0510 +0.0512 178 187 178 187
std::is_permutation(list<int>) (4leg) (shuffled)/1024 +0.0025 +0.0023 4572262 4583785 4572271 4582837
rng::is_permutation(vector<int>) (4leg) (shuffled)/8 +0.0969 +0.0972 97 107 97 107
rng::is_permutation(vector<int>) (4leg) (shuffled)/1024 +0.0391 +0.0389 699073 726408 699069 726263
rng::is_permutation(deque<int>) (4leg) (shuffled)/8 +0.0250 +0.0252 237 243 237 243
rng::is_permutation(deque<int>) (4leg) (shuffled)/1024 -0.0002 -0.0003 3195994 3195224 3195984 3194958
rng::is_permutation(list<int>) (4leg) (shuffled)/8 +0.0478 +0.0480 178 187 178 187
rng::is_permutation(list<int>) (4leg) (shuffled)/1024 -0.0006 -0.0008 4568130 4565219 4568106 4564267
std::is_permutation(vector<int>) (4leg, pred) (shuffled)/8 +0.2592 +0.2594 114 144 114 144
std::is_permutation(vector<int>) (4leg, pred) (shuffled)/1024 +0.2197 +0.2197 1614028 1968680 1614019 1968684
std::is_permutation(deque<int>) (4leg, pred) (shuffled)/8 -0.2631 -0.2629 230 170 230 170
std::is_permutation(deque<int>) (4leg, pred) (shuffled)/1024 -0.3086 -0.3086 3197877 2210887 3197836 2210891
std::is_permutation(list<int>) (4leg, pred) (shuffled)/8 -0.0263 -0.0263 141 137 141 137
std::is_permutation(list<int>) (4leg, pred) (shuffled)/1024 +0.0190 +0.0190 4998838 5093826 4998848 5093802
rng::is_permutation(vector<int>) (4leg, pred) (shuffled)/8 +0.2610 +0.2607 114 144 114 144
rng::is_permutation(vector<int>) (4leg, pred) (shuffled)/1024 +0.2236 +0.2239 1611720 1972173 1611370 1972142
rng::is_permutation(deque<int>) (4leg, pred) (shuffled)/8 -0.2045 -0.2046 214 171 214 170
rng::is_permutation(deque<int>) (4leg, pred) (shuffled)/1024 -0.2350 -0.2348 2886941 2208494 2886321 2208498
rng::is_permutation(list<int>) (4leg, pred) (shuffled)/8 +0.0041 +0.0041 142 142 142 142
rng::is_permutation(list<int>) (4leg, pred) (shuffled)/1024 +0.0173 +0.0171 5016855 5103609 5016866 5102603
OVERALL_GEOMEAN -0.1017 -0.1017 0 0 0 0
```
</details>
<details>
<summary>Clang v19 results (Mean Time: -0.0432)</summary>
```
Benchmark Time CPU Time Old Time New CPU Old CPU New
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
std::is_permutation(vector<int>) (3leg) (common prefix)/8 -0.1945 -0.1948 8 6 8 6
std::is_permutation(vector<int>) (3leg) (common prefix)/1024 -0.7643 -0.7644 834 197 834 197
std::is_permutation(vector<int>) (3leg) (common prefix)/8192 -0.7233 -0.7233 6601 1826 6599 1826
std::is_permutation(deque<int>) (3leg) (common prefix)/8 -0.0177 -0.0174 21 20 21 20
std::is_permutation(deque<int>) (3leg) (common prefix)/1024 -0.0006 -0.0006 2074 2073 2074 2073
std::is_permutation(deque<int>) (3leg) (common prefix)/8192 -0.0014 -0.0011 16578 16555 16574 16555
std::is_permutation(list<int>) (3leg) (common prefix)/8 +0.0014 +0.0012 10 10 10 10
std::is_permutation(list<int>) (3leg) (common prefix)/1024 +0.0006 +0.0009 3100 3102 3099 3102
std::is_permutation(list<int>) (3leg) (common prefix)/8192 -0.0033 -0.0035 30416 30314 30415 30308
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/8 +0.0045 +0.0045 10 10 10 10
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/1024 +0.0003 +0.0003 1255 1256 1255 1256
std::is_permutation(vector<int>) (3leg, pred) (common prefix)/8192 -0.0040 -0.0040 10225 10184 10225 10184
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/8 -0.1690 -0.1688 24 20 24 20
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/1024 -0.3387 -0.3389 2491 1647 2490 1647
std::is_permutation(deque<int>) (3leg, pred) (common prefix)/8192 -0.3220 -0.3219 19882 13480 19878 13480
std::is_permutation(list<int>) (3leg, pred) (common prefix)/8 +0.4666 +0.4663 15 22 15 22
std::is_permutation(list<int>) (3leg, pred) (common prefix)/1024 +0.0049 +0.0051 3387 3403 3386 3403
std::is_permutation(list<int>) (3leg, pred) (common prefix)/8192 -0.0165 -0.0167 33380 32829 33379 32823
std::is_permutation(vector<int>) (4leg) (common prefix)/8 +0.2052 +0.2055 13 16 13 16
std::is_permutation(vector<int>) (4leg) (common prefix)/1024 -0.1408 -0.1409 980 842 980 842
std::is_permutation(vector<int>) (4leg) (common prefix)/8192 -0.1459 -0.1459 7732 6604 7732 6604
std::is_permutation(deque<int>) (4leg) (common prefix)/8 -0.0580 -0.0582 29 27 29 27
std::is_permutation(deque<int>) (4leg) (common prefix)/1024 -0.4535 -0.4535 2312 1263 2312 1263
std::is_permutation(deque<int>) (4leg) (common prefix)/8192 -0.3989 -0.3989 16638 10000 16638 10000
std::is_permutation(list<int>) (4leg) (common prefix)/8 -0.1670 -0.1672 19 15 19 15
std::is_permutation(list<int>) (4leg) (common prefix)/1024 -0.0576 -0.0576 3308 3117 3308 3117
std::is_permutation(list<int>) (4leg) (common prefix)/8192 -0.0437 -0.0439 30965 29613 30965 29607
rng::is_permutation(vector<int>) (4leg) (common prefix)/8 +0.3785 +0.3785 15 20 15 20
rng::is_permutation(vector<int>) (4leg) (common prefix)/1024 +0.2810 +0.2807 980 1255 980 1255
rng::is_permutation(vector<int>) (4leg) (common prefix)/8192 +0.2788 +0.2791 7742 9901 7740 9900
rng::is_permutation(deque<int>) (4leg) (common prefix)/8 +0.1996 +0.1993 30 36 30 36
rng::is_permutation(deque<int>) (4leg) (common prefix)/1024 +0.1962 +0.1964 2086 2496 2086 2496
rng::is_permutation(deque<int>) (4leg) (common prefix)/8192 +0.1984 +0.1982 16579 19869 16578 19864
rng::is_permutation(list<int>) (4leg) (common prefix)/8 -0.1446 -0.1444 20 17 20 17
rng::is_permutation(list<int>) (4leg) (common prefix)/1024 -0.0227 -0.0229 3298 3223 3298 3222
rng::is_permutation(list<int>) (4leg) (common prefix)/8192 +0.0217 +0.0219 30209 30865 30203 30864
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/8 -0.0525 -0.0527 14 14 14 14
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/1024 -0.0028 -0.0028 1262 1259 1262 1259
std::is_permutation(vector<int>) (4leg, pred) (common prefix)/8192 -0.0022 -0.0022 10214 10192 10214 10192
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/8 +0.0227 +0.0227 34 35 34 35
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/1024 -0.2779 -0.2779 2332 1684 2332 1684
std::is_permutation(deque<int>) (4leg, pred) (common prefix)/8192 -0.2484 -0.2485 18256 13721 18256 13719
std::is_permutation(list<int>) (4leg, pred) (common prefix)/8 +0.2689 +0.2692 18 23 18 23
std::is_permutation(list<int>) (4leg, pred) (common prefix)/1024 +0.0153 +0.0151 3392 3444 3392 3443
std::is_permutation(list<int>) (4leg, pred) (common prefix)/8192 -0.0004 -0.0004 32784 32772 32784 32772
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/8 -0.0001 -0.0002 13 13 13 13
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/1024 -0.0020 -0.0018 1260 1257 1260 1257
rng::is_permutation(vector<int>) (4leg, pred) (common prefix)/8192 -0.0018 -0.0020 10212 10193 10212 10191
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/8 +0.1278 +0.1280 35 40 35 40
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/1024 +0.3906 +0.3904 2389 3322 2389 3321
rng::is_permutation(deque<int>) (4leg, pred) (common prefix)/8192 +0.4481 +0.4484 18273 26461 18269 26460
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/8 +0.0369 +0.0367 18 18 18 18
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/1024 +0.0184 +0.0184 3361 3422 3360 3422
rng::is_permutation(list<int>) (4leg, pred) (common prefix)/8192 +0.0048 +0.0046 32902 33058 32901 33052
std::is_permutation(vector<int>) (3leg) (shuffled)/8 +0.0309 +0.0311 89 92 89 92
std::is_permutation(vector<int>) (3leg) (shuffled)/1024 +0.0018 +0.0016 740186 741545 740187 741391
std::is_permutation(deque<int>) (3leg) (shuffled)/8 +0.1159 +0.1159 207 231 207 231
std::is_permutation(deque<int>) (3leg) (shuffled)/1024 +0.0364 +0.0362 2880767 2985747 2880763 2985161
std::is_permutation(list<int>) (3leg) (shuffled)/8 -0.0325 -0.0325 124 120 124 120
std::is_permutation(list<int>) (3leg) (shuffled)/1024 +0.0028 +0.0026 4548789 4561714 4548749 4560792
std::is_permutation(vector<int>) (3leg, pred) (shuffled)/8 -0.0345 -0.0345 179 173 179 173
std::is_permutation(vector<int>) (3leg, pred) (shuffled)/1024 +0.0062 +0.0064 2518745 2534408 2518246 2534367
std::is_permutation(deque<int>) (3leg, pred) (shuffled)/8 -0.0345 -0.0345 220 212 220 212
std::is_permutation(deque<int>) (3leg, pred) (shuffled)/1024 -0.0335 -0.0335 3255446 3146391 3255453 3146396
std::is_permutation(list<int>) (3leg, pred) (shuffled)/8 +0.2016 +0.2016 240 288 240 288
std::is_permutation(list<int>) (3leg, pred) (shuffled)/1024 +0.0732 +0.0734 5245407 5629350 5244347 5629361
std::is_permutation(vector<int>) (4leg) (shuffled)/8 -0.0712 -0.0713 95 88 95 88
std::is_permutation(vector<int>) (4leg) (shuffled)/1024 -0.0154 -0.0152 748810 737291 748663 737287
std::is_permutation(deque<int>) (4leg) (shuffled)/8 -0.1044 -0.1046 170 152 170 152
std::is_permutation(deque<int>) (4leg) (shuffled)/1024 -0.1254 -0.1254 2352579 2057488 2352583 2057480
std::is_permutation(list<int>) (4leg) (shuffled)/8 +0.1322 +0.1322 109 124 109 124
std::is_permutation(list<int>) (4leg) (shuffled)/1024 -0.0016 -0.0016 4546353 4539198 4546362 4539183
rng::is_permutation(vector<int>) (4leg) (shuffled)/8 -0.0128 -0.0128 90 89 90 89
rng::is_permutation(vector<int>) (4leg) (shuffled)/1024 -0.0044 -0.0044 740259 737016 740250 737017
rng::is_permutation(deque<int>) (4leg) (shuffled)/8 -0.2595 -0.2594 205 152 205 152
rng::is_permutation(deque<int>) (4leg) (shuffled)/1024 -0.2895 -0.2896 2895451 2057357 2895438 2056940
rng::is_permutation(list<int>) (4leg) (shuffled)/8 -0.0137 -0.0135 126 125 126 125
rng::is_permutation(list<int>) (4leg) (shuffled)/1024 -0.0014 -0.0016 4546535 4540369 4546517 4539459
std::is_permutation(vector<int>) (4leg, pred) (shuffled)/8 -0.0409 -0.0407 182 174 181 174
std::is_permutation(vector<int>) (4leg, pred) (shuffled)/1024 +0.0039 +0.0037 2525031 2534863 2525025 2534369
std::is_permutation(deque<int>) (4leg, pred) (shuffled)/8 +0.0279 +0.0281 232 238 232 238
std::is_permutation(deque<int>) (4leg, pred) (shuffled)/1024 -0.0610 -0.0612 3468556 3256934 3468542 3256312
std::is_permutation(list<int>) (4leg, pred) (shuffled)/8 +0.0950 +0.0952 187 205 187 205
std::is_permutation(list<int>) (4leg, pred) (shuffled)/1024 +0.0738 +0.0736 5251369 5638866 5251348 5637750
rng::is_permutation(vector<int>) (4leg, pred) (shuffled)/8 -0.0417 -0.0417 181 174 181 174
rng::is_permutation(vector<int>) (4leg, pred) (shuffled)/1024 +0.0051 +0.0049 2522761 2535627 2522749 2535110
rng::is_permutation(deque<int>) (4leg, pred) (shuffled)/8 -0.0175 -0.0175 225 221 225 221
rng::is_permutation(deque<int>) (4leg, pred) (shuffled)/1024 -0.0944 -0.0946 3470871 3143225 3470857 3142614
rng::is_permutation(list<int>) (4leg, pred) (shuffled)/8 +0.0917 +0.0919 240 262 240 262
rng::is_permutation(list<int>) (4leg, pred) (shuffled)/1024 +0.0756 +0.0756 5237991 5634083 5238002 5634094
OVERALL_GEOMEAN -0.0432 -0.0432 0 0 0 0
```
</details>
https://github.com/llvm/llvm-project/pull/129565
More information about the libcxx-commits
mailing list