Last active
September 11, 2023 21:25
-
-
Save technicalpickles/91933d34dcd47bfc99d6ac0e53fcdb1e to your computer and use it in GitHub Desktop.
Bundler::Settings#[] benchmark, see https://github.com/rubygems/rubygems/pull/6923
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "benchmark/ips" | |
require "benchmark/memory" | |
require 'bundler' | |
class Bundler::Settings | |
def original(name) | |
key = key_for(name) | |
value = configs.values.map {|config| config[key] }.compact.first | |
converted_value(value, name) | |
end | |
def bang_method(name) | |
key = key_for(name) | |
values = configs.values | |
values.map! {|config| config[key] } | |
values.compact! | |
value = values.first | |
converted_value(value, name) | |
end | |
def with_detect(name) | |
key = key_for(name) | |
config_with_key = configs.values.detect {|config| config[key] } | |
value = config_with_key[key] if config_with_key | |
converted_value(value, name) | |
end | |
def with_detect_with_memoized_configs(name) | |
key = key_for(name) | |
config_with_key = configs.values.detect {|config| config[key] } | |
value = config_with_key[key] if config_with_key | |
converted_value(value, name) | |
end | |
def manual_loop(name) | |
key = key_for(name) | |
value = nil | |
configs.each do |_, config| | |
if config[key] | |
value = config[key] | |
break | |
end | |
end | |
converted_value(value, name) | |
end | |
def manual_loop_with_memoized_configs(name) | |
key = key_for(name) | |
value = nil | |
memoized_configs.each do |_, config| | |
if config[key] | |
value = config[key] | |
break | |
end | |
end | |
converted_value(value, name) | |
end | |
def correct_manual_loop(name) | |
key = key_for(name) | |
value = nil | |
configs.each do |_, config| | |
value = config[key] | |
next if value.nil? | |
break | |
end | |
converted_value(value, name) | |
end | |
def correct_manual_loop_with_memoized_configs(name) | |
key = key_for(name) | |
value = nil | |
memoized_configs.each do |_, config| | |
value = config[key] | |
next if value.nil? | |
break | |
end | |
converted_value(value, name) | |
end | |
def correct_manual_with_each_config(name) | |
key = key_for(name) | |
value = nil | |
each_config do |config| | |
value = config[key] | |
next if value.nil? | |
break | |
end | |
converted_value(value, name) | |
end | |
def with_flat_map(name) | |
key = key_for(name) | |
value = configs.flat_map {|_, config| break config[key] unless config[key].nil? } | |
converted_value(value, name) | |
end | |
private | |
def each_config | |
yield @temporary | |
yield @local_config | |
yield @env_config | |
yield @global_config | |
yield DEFAULT_CONFIG | |
end | |
def memoized_configs | |
@memoized_configs ||= { | |
:temporary => @temporary, | |
:local => @local_config, | |
:env => @env_config, | |
:global => @global_config, | |
:default => DEFAULT_CONFIG, | |
}.freeze | |
end | |
end | |
# warm up memoization | |
Bundler.settings.manual_loop_with_memoized_configs(:silence_deprecations) | |
Benchmark.memory do |x| | |
x.report("original") { Bundler.settings.original(:force_ruby_platform) } | |
x.report("bang_method") { Bundler.settings.bang_method(:force_ruby_platform) } | |
x.report("with_detect") { Bundler.settings.with_detect(:force_ruby_platform) } | |
x.report("with_detect w/ memoized configs") { Bundler.settings.with_detect_with_memoized_configs(:force_ruby_platform) } | |
x.report("manual_loop") { Bundler.settings.manual_loop(:force_ruby_platform) } | |
x.report("manual_loop w/ memoized configs") { Bundler.settings.manual_loop_with_memoized_configs(:force_ruby_platform) } | |
x.report("correct manual_loop") { Bundler.settings.correct_manual_loop(:force_ruby_platform) } | |
x.report("correct manual_loop w/ memoized configs") { Bundler.settings.correct_manual_loop_with_memoized_configs(:force_ruby_platform) } | |
x.report("correct manual_loop w/ each_config") { Bundler.settings.correct_manual_with_each_config(:force_ruby_platform) } | |
x.report("with_flat_map") { Bundler.settings.with_flat_map(:force_ruby_platform) } | |
x.compare! | |
end | |
Benchmark.ips do |x| | |
x.report("original") { Bundler.settings.original(:force_ruby_platform) } | |
x.report("bang_method") { Bundler.settings.bang_method(:force_ruby_platform) } | |
x.report("with_detect") { Bundler.settings.with_detect(:force_ruby_platform) } | |
x.report("with_detect w/ memoized configs") { Bundler.settings.with_detect_with_memoized_configs(:force_ruby_platform) } | |
x.report("manual_loop") { Bundler.settings.manual_loop(:force_ruby_platform) } | |
x.report("manual_loop w/ memoized configs") { Bundler.settings.manual_loop_with_memoized_configs(:force_ruby_platform) } | |
x.report("correct manual_loop") { Bundler.settings.correct_manual_loop(:force_ruby_platform) } | |
x.report("correct manual_loop w/ memoized configs") { Bundler.settings.correct_manual_loop_with_memoized_configs(:force_ruby_platform) } | |
x.report("correct manual_loop w/ each_config") { Bundler.settings.correct_manual_with_each_config(:force_ruby_platform) } | |
x.report("with_flat_map") { Bundler.settings.with_flat_map(:force_ruby_platform) } | |
x.compare! order: :baseline | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Calculating ------------------------------------- | |
original 720.000 memsize ( 0.000 retained) | |
10.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
bang_method 560.000 memsize ( 0.000 retained) | |
8.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
with_detect 560.000 memsize ( 80.000 retained) | |
8.000 objects ( 1.000 retained) | |
3.000 strings ( 0.000 retained) | |
with_detect w/ memoized configs | |
560.000 memsize ( 0.000 retained) | |
8.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
manual_loop 480.000 memsize ( 0.000 retained) | |
7.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
manual_loop w/ memoized configs | |
312.000 memsize ( 72.000 retained) | |
6.000 objects ( 1.000 retained) | |
3.000 strings ( 1.000 retained) | |
correct manual_loop 480.000 memsize ( 0.000 retained) | |
7.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
correct manual_loop w/ memoized configs | |
312.000 memsize ( 72.000 retained) | |
6.000 objects ( 1.000 retained) | |
3.000 strings ( 1.000 retained) | |
correct manual_loop w/ each_config | |
312.000 memsize ( 0.000 retained) | |
6.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
with_flat_map 920.000 memsize ( 168.000 retained) | |
14.000 objects ( 1.000 retained) | |
3.000 strings ( 0.000 retained) | |
Comparison: | |
correct manual_loop w/ memoized configs: 312 allocated | |
manual_loop w/ memoized configs: 312 allocated - same | |
correct manual_loop w/ each_config: 312 allocated - same | |
correct manual_loop: 480 allocated - 1.54x more | |
manual_loop: 480 allocated - 1.54x more | |
with_detect: 560 allocated - 1.79x more | |
with_detect w/ memoized configs: 560 allocated - 1.79x more | |
bang_method: 560 allocated - 1.79x more | |
original: 720 allocated - 2.31x more | |
with_flat_map: 920 allocated - 2.95x more | |
Warming up -------------------------------------- | |
original 90.970k i/100ms | |
bang_method 90.281k i/100ms | |
with_detect 85.338k i/100ms | |
with_detect w/ memoized configs | |
89.005k i/100ms | |
manual_loop 92.693k i/100ms | |
manual_loop w/ memoized configs | |
103.907k i/100ms | |
correct manual_loop 88.976k i/100ms | |
correct manual_loop w/ memoized configs | |
100.113k i/100ms | |
correct manual_loop w/ each_config | |
112.645k i/100ms | |
with_flat_map 52.569k i/100ms | |
Calculating ------------------------------------- | |
original 900.679k (± 2.7%) i/s - 4.548M in 5.054191s | |
bang_method 921.335k (± 5.2%) i/s - 4.604M in 5.017818s | |
with_detect 874.357k (± 1.2%) i/s - 4.438M in 5.075983s | |
with_detect w/ memoized configs | |
874.308k (± 1.0%) i/s - 4.450M in 5.090577s | |
manual_loop 923.377k (± 0.9%) i/s - 4.635M in 5.019649s | |
manual_loop w/ memoized configs | |
1.042M (± 1.5%) i/s - 5.299M in 5.087562s | |
correct manual_loop 892.766k (± 1.2%) i/s - 4.538M in 5.083618s | |
correct manual_loop w/ memoized configs | |
1.023M (± 0.7%) i/s - 5.206M in 5.086753s | |
correct manual_loop w/ each_config | |
1.136M (± 0.7%) i/s - 5.745M in 5.058002s | |
with_flat_map 540.224k (± 0.7%) i/s - 2.734M in 5.060378s | |
Comparison: | |
original: 900679.3 i/s | |
correct manual_loop w/ each_config: 1135861.2 i/s - 1.26x faster | |
manual_loop w/ memoized configs: 1041836.7 i/s - 1.16x faster | |
correct manual_loop w/ memoized configs: 1023470.5 i/s - 1.14x faster | |
manual_loop: 923377.4 i/s - same-ish: difference falls within error | |
bang_method: 921335.0 i/s - same-ish: difference falls within error | |
correct manual_loop: 892766.1 i/s - same-ish: difference falls within error | |
with_detect: 874357.4 i/s - same-ish: difference falls within error | |
with_detect w/ memoized configs: 874308.3 i/s - same-ish: difference falls within error | |
with_flat_map: 540224.1 i/s - 1.67x slower |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment