Improve performance of Gitlab::Utils::InlineHash
We can actually be 1.2 to 4x faster with a small tweak. But overall this is good enough, so let's follow-up this at a later stage.
Benchmarks for small
Calculating -------------------------------------
small recur 12.311k i/100ms
small iter unshift 20.838k i/100ms
small iter unshift no prefix
23.162k i/100ms
-------------------------------------------------
small recur 143.455k (± 7.5%) i/s - 714.038k
small iter unshift 239.523k (± 5.5%) i/s - 1.209M
small iter unshift no prefix
298.997k (± 8.2%) i/s - 1.506M
Comparison:
small iter unshift no prefix: 298997.0 i/s
small iter unshift: 239522.5 i/s - 1.25x slower
small recur: 143455.3 i/s - 2.08x slower
================================================================================
Benchmarks for medium
Calculating -------------------------------------
medium recur 946.000 i/100ms
medium iter unshift 1.723k i/100ms
medium iter unshift no prefix
5.028k i/100ms
-------------------------------------------------
medium recur 9.918k (± 6.3%) i/s - 50.138k
medium iter unshift 17.232k (± 8.4%) i/s - 86.150k
medium iter unshift no prefix
57.738k (± 3.5%) i/s - 291.624k
Comparison:
medium iter unshift no prefix: 57738.2 i/s
medium iter unshift: 17232.1 i/s - 3.35x slower
medium recur: 9917.5 i/s - 5.82x slower
================================================================================
Benchmarks for large
Calculating -------------------------------------
large recur 50.000 i/100ms
large iter unshift 78.000 i/100ms
large iter unshift no prefix
316.000 i/100ms
-------------------------------------------------
large recur 515.679 (± 3.3%) i/s - 2.600k
large iter unshift 785.427 (± 1.9%) i/s - 3.978k
large iter unshift no prefix
3.199k (± 2.3%) i/s - 16.116k
Comparison:
large iter unshift no prefix: 3198.9 i/s
large iter unshift: 785.4 i/s - 4.07x slower
large recur: 515.7 i/s - 6.20x slower
================================================================================
Benchmarks for huge
Calculating -------------------------------------
huge recur 9.000 i/100ms
huge iter unshift 12.000 i/100ms
huge iter unshift no prefix
55.000 i/100ms
-------------------------------------------------
huge recur 90.355 (± 8.9%) i/s - 450.000
huge iter unshift 143.729 (± 7.7%) i/s - 720.000
huge iter unshift no prefix
576.654 (± 5.4%) i/s - 2.915k
Comparison:
huge iter unshift no prefix: 576.7 i/s
huge iter unshift: 143.7 i/s - 4.01x slower
huge recur: 90.4 i/s - 6.38x slower
================================================================================
The following discussions from !16441 (merged) should be addressed:
-
@tkuah started a discussion: describe '.merge_keys!' do
-
@tkuah started a discussion: pairs = if prefix hash.map { |key, value| ["#{base_prefix}#{key}", value] } else hash.to_a end
If
prefix
is nil, we can save ourselves iterating the hash twice. Or we can get rid of theprefix:
if not needed.
Edited by Vitali Tatarintev