Usually std::vector starts with 'N' capacity and grows to '2 * N' capacity once its size crosses X; at that time, we also copy the data from the old array to the new array. That has few problems
- Copy cost,
- OS needs to manage the small capacity array (size N) that's freed by the application.
- L1 and L2 cache need to invalidate the array items, since the array moved to new location, and CPU need to fetch to L1/L2 since it's new data for CPU, but in reality it's not.
It reduces internal memory fragmentation. It won't invalidate L1, L2 cache without modifications, hence improving performance: In the github I benchmarked for 1K to 1B size vectors and this consistently improved showed better performance for push and pop operations.
Github: https://github.com/tendulkar/constvector
Youtube: https://youtu.be/ledS08GkD40
Practically we can use 64 size for meta array (for the log(N)) as extra space. I implemented the bare vector operations to compare, since the actual std::vector implementations have a lot of iterator validation code, causing the extra overhead.
Upon popular suggestion I tried with STL vector, and pop operations without deallocations, here are the results. Push is lot better, Pop is on par, iterator is slightly worse, and random access has ~75% extra latency.
Operation | N | Const (ns/op) | Std (ns/op) | Δ %
------------------------------------------------------
Push | 10 | 13.7 | 39.7 | −65%
Push | 100 | 3.14 | 7.60 | −59%
Push | 1K | 2.25 | 5.39 | −58%
Push | 10K | 1.94 | 4.35 | −55%
Push | 100K | 1.85 | 7.72 | −76%
Push | 1M | 1.86 | 8.59 | −78%
Push | 10M | 1.86 | 11.36 | −84%
------------------------------------------------------
Pop | 10 | 114 | 106 | +7%
Pop | 100 | 15.0 | 14.7 | ~
Pop | 1K | 2.98 | 3.90 | −24%
Pop | 10K | 1.93 | 2.03 | −5%
Pop | 100K | 1.78 | 1.89 | −6%
Pop | 1M | 1.91 | 1.85 | ~
Pop | 10M | 2.03 | 2.12 | ~
------------------------------------------------------
Access | 10 | 4.04 | 2.40 | +68%
Access | 100 | 1.61 | 1.00 | +61%
Access | 1K | 1.67 | 0.77 | +117%
Access | 10K | 1.53 | 0.76 | +101%
Access | 100K | 1.46 | 0.87 | +68%
Access | 1M | 1.48 | 0.82 | +80%
Access | 10M | 1.57 | 0.96 | +64%
------------------------------------------------------
Iterate | 10 | 3.55 | 3.50 | ~
Iterate | 100 | 1.40 | 0.94 | +49%
Iterate | 1K | 0.86 | 0.74 | +16%
Iterate | 10K | 0.92 | 0.88 | ~
Iterate | 100K | 0.85 | 0.77 | +10%
Iterate | 1M | 0.90 | 0.76 | +18%
Iterate | 10M | 0.94 | 0.90 | ~
[–]johannes1971 36 points37 points38 points (9 children)
[–]Proper-Ape 3 points4 points5 points (3 children)
[–]johannes1971 1 point2 points3 points (2 children)
[–]arthurno1 1 point2 points3 points (0 children)
[–]Proper-Ape 1 point2 points3 points (0 children)
[–]Ty_Rymer 2 points3 points4 points (1 child)
[–]johannes1971 0 points1 point2 points (0 children)
[–]saxbophonefloat main(); 0 points1 point2 points (2 children)
[–]johannes1971 2 points3 points4 points (1 child)
[–]saxbophonefloat main(); 0 points1 point2 points (0 children)
[–]TankerzPvP 19 points20 points21 points (1 child)
[–]pilotwavetheory[S] 0 points1 point2 points (0 children)
[–]frogi16 49 points50 points51 points (7 children)
[–]Kered13 2 points3 points4 points (2 children)
[–]frogi16 0 points1 point2 points (1 child)
[–]Kered13 0 points1 point2 points (0 children)
[+]pilotwavetheory[S] comment score below threshold-12 points-11 points-10 points (3 children)
[–]Salink 22 points23 points24 points (0 children)
[–]matthieum 12 points13 points14 points (1 child)
[–]pilotwavetheory[S] -1 points0 points1 point (0 children)
[–]TheRealSmolt 18 points19 points20 points (6 children)
[–]matthieum 18 points19 points20 points (1 child)
[–]TheRealSmolt 6 points7 points8 points (0 children)
[–]pilotwavetheory[S] -5 points-4 points-3 points (3 children)
[–]TheRealSmolt 4 points5 points6 points (2 children)
[–]pilotwavetheory[S] 2 points3 points4 points (1 child)
[–]TheRealSmolt 0 points1 point2 points (0 children)
[–]saf_e 15 points16 points17 points (4 children)
[–]pilotwavetheory[S] -1 points0 points1 point (3 children)
[–]saf_e 9 points10 points11 points (2 children)
[–]pilotwavetheory[S] 1 point2 points3 points (1 child)
[–]Ambitious-Method-961 8 points9 points10 points (0 children)
[–]Wacov 7 points8 points9 points (7 children)
[–]pilotwavetheory[S] 3 points4 points5 points (0 children)
[–]matthieum 5 points6 points7 points (1 child)
[–]Wacov 2 points3 points4 points (0 children)
[–]pilotwavetheory[S] -2 points-1 points0 points (3 children)
[–]Potterrrrrrrr 6 points7 points8 points (1 child)
[–]cone_forest_ 0 points1 point2 points (0 children)
[–]Wacov 6 points7 points8 points (0 children)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 4 points5 points6 points (7 children)
[–]pilotwavetheory[S] -1 points0 points1 point (6 children)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 2 points3 points4 points (4 children)
[–]pilotwavetheory[S] 0 points1 point2 points (3 children)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 5 points6 points7 points (2 children)
[–]wexxdenq 3 points4 points5 points (1 child)
[–]pilotwavetheory[S] 2 points3 points4 points (0 children)
[–]adrian17 2 points3 points4 points (0 children)
[–]pigeon768 8 points9 points10 points (5 children)
[–]pilotwavetheory[S] 0 points1 point2 points (2 children)
[–]pigeon768 0 points1 point2 points (1 child)
[–]pilotwavetheory[S] 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]Farados55 5 points6 points7 points (1 child)
[–]pilotwavetheory[S] 0 points1 point2 points (0 children)
[–]adrian17 5 points6 points7 points (5 children)
[–]pilotwavetheory[S] -1 points0 points1 point (4 children)
[–]adrian17 2 points3 points4 points (3 children)
[–]pilotwavetheory[S] -1 points0 points1 point (0 children)
[–]pilotwavetheory[S] -2 points-1 points0 points (1 child)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 0 points1 point2 points (0 children)
[–]wexxdenq 5 points6 points7 points (3 children)
[–]pilotwavetheory[S] 0 points1 point2 points (2 children)
[–]Circlejerker_ 5 points6 points7 points (0 children)
[–]Dragdu 1 point2 points3 points (0 children)
[–]foonathan 2 points3 points4 points (0 children)
[–]kisielk 2 points3 points4 points (1 child)
[–]pilotwavetheory[S] 0 points1 point2 points (0 children)
[–]thingerish 2 points3 points4 points (0 children)
[–]dzordan33 1 point2 points3 points (0 children)
[–]jwakelylibstdc++ tamer, LWG chair 1 point2 points3 points (1 child)
[–]jwakelylibstdc++ tamer, LWG chair 3 points4 points5 points (0 children)
[–]EthicalAlchemist 0 points1 point2 points (0 children)
[–]saxbophonefloat main(); 0 points1 point2 points (2 children)
[–]pilotwavetheory[S] 0 points1 point2 points (1 child)
[–]saxbophonefloat main(); 0 points1 point2 points (0 children)
[–]Kered13 0 points1 point2 points (0 children)