Last active
January 9, 2025 09:19
-
-
Save mhenrixon/e5cbb65c62862c82675692bd3c715fc8 to your computer and use it in GitHub Desktop.
Benchmark and compare various ways to access the ENV variable in ruby
This file contains 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
#!/usr/bin/env ruby | |
# frozen_string_literal: true | |
require 'benchmark/ips' | |
require 'benchmark/memory' | |
# Set up test environment variables | |
ENV['TEST_KEY1'] = 'some_value' | |
ENV['TEST_KEY2'] = 'another_value' | |
ENV['TEST_KEY3'] = 'third_value' | |
# Create class similar to Rails.application.credentials | |
class MockCredentials | |
def initialize | |
@values = { | |
test_key1: 'some_value', | |
test_key2: 'another_value', | |
test_key3: 'third_value' | |
} | |
end | |
def dig(*keys) | |
@values.dig(*keys) | |
end | |
end | |
# Create cached hash version | |
CACHED_ENV = ENV.to_h | |
credentials = MockCredentials.new | |
puts "Performance Benchmark (iterations per second):" | |
puts "============================================" | |
Benchmark.ips do |x| | |
x.config(time: 5, warmup: 2) | |
x.report("ENV['KEY'] direct access") do | |
ENV['TEST_KEY1'] | |
ENV['TEST_KEY2'] | |
ENV['TEST_KEY3'] | |
end | |
x.report("ENV.fetch direct access") do | |
ENV.fetch('TEST_KEY1') | |
ENV.fetch('TEST_KEY2') | |
ENV.fetch('TEST_KEY3') | |
end | |
x.report("Cached ENV hash access") do | |
CACHED_ENV['TEST_KEY1'] | |
CACHED_ENV['TEST_KEY2'] | |
CACHED_ENV['TEST_KEY3'] | |
end | |
x.report("credentials-style access") do | |
credentials.dig(:test_key1) | |
credentials.dig(:test_key2) | |
credentials.dig(:test_key3) | |
end | |
x.compare! | |
end | |
puts "\nMemory Usage:" | |
puts "=============" | |
Benchmark.memory do |x| | |
x.report("ENV['KEY'] direct access") do | |
100.times do | |
ENV['TEST_KEY1'] | |
ENV['TEST_KEY2'] | |
ENV['TEST_KEY3'] | |
end | |
end | |
x.report("ENV.fetch direct access") do | |
100.times do | |
ENV.fetch('TEST_KEY1') | |
ENV.fetch('TEST_KEY2') | |
ENV.fetch('TEST_KEY3') | |
end | |
end | |
x.report("Cached ENV hash access") do | |
100.times do | |
CACHED_ENV['TEST_KEY1'] | |
CACHED_ENV['TEST_KEY2'] | |
CACHED_ENV['TEST_KEY3'] | |
end | |
end | |
x.report("credentials-style access") do | |
100.times do | |
credentials.dig(:test_key1) | |
credentials.dig(:test_key2) | |
credentials.dig(:test_key3) | |
end | |
end | |
x.compare! | |
end |
This file contains 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
Performance Benchmark (iterations per second): | |
============================================ | |
ruby 2.3.8p459 (2018-10-18 revision 65136) [aarch64-linux] | |
Warming up -------------------------------------- | |
ENV['KEY'] direct access | |
153.285k i/100ms | |
ENV.fetch direct access | |
156.696k i/100ms | |
Cached ENV hash access | |
571.329k i/100ms | |
credentials-style access | |
257.128k i/100ms | |
Calculating ------------------------------------- | |
ENV['KEY'] direct access | |
1.572M (± 1.3%) i/s (636.05 ns/i) - 7.971M in 5.070658s | |
ENV.fetch direct access | |
1.562M (± 1.8%) i/s (640.17 ns/i) - 7.835M in 5.017175s | |
Cached ENV hash access | |
5.702M (± 2.3%) i/s (175.39 ns/i) - 28.566M in 5.012782s | |
credentials-style access | |
2.602M (± 2.2%) i/s (384.27 ns/i) - 13.114M in 5.041605s | |
Comparison: | |
Cached ENV hash access: 5701655.1 i/s | |
credentials-style access: 2602305.8 i/s - 2.19x slower | |
ENV['KEY'] direct access: 1572197.8 i/s - 3.63x slower | |
ENV.fetch direct access: 1562085.0 i/s - 3.65x slower | |
Memory Usage: | |
============= | |
Calculating ------------------------------------- | |
ENV['KEY'] direct access | |
24.000k memsize ( 0.000 retained) | |
600.000 objects ( 0.000 retained) | |
6.000 strings ( 0.000 retained) | |
ENV.fetch direct access | |
12.000k memsize ( 0.000 retained) | |
300.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
Cached ENV hash access | |
0.000 memsize ( 0.000 retained) | |
0.000 objects ( 0.000 retained) | |
0.000 strings ( 0.000 retained) | |
credentials-style access | |
24.000k memsize ( 0.000 retained) | |
600.000 objects ( 0.000 retained) | |
0.000 strings ( 0.000 retained) | |
Comparison: | |
Cached ENV hash access: 0 allocated | |
ENV.fetch direct access: 12000 allocated - Infx more | |
ENV['KEY'] direct access: 24000 allocated - Infx more | |
credentials-style access: 24000 allocated - Infx more |
This file contains 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
Performance Benchmark (iterations per second): | |
============================================ | |
ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [arm64-darwin24] | |
Warming up -------------------------------------- | |
ENV['KEY'] direct access | |
146.202k i/100ms | |
ENV.fetch direct access | |
138.816k i/100ms | |
Cached ENV hash access | |
1.292M i/100ms | |
credentials-style access | |
441.103k i/100ms | |
Calculating ------------------------------------- | |
ENV['KEY'] direct access | |
1.441M (± 1.6%) i/s (693.97 ns/i) - 7.310M in 5.074315s | |
ENV.fetch direct access | |
1.414M (± 2.0%) i/s (707.27 ns/i) - 7.080M in 5.009181s | |
Cached ENV hash access | |
14.212M (± 1.2%) i/s (70.36 ns/i) - 72.334M in 5.090395s | |
credentials-style access | |
4.616M (± 2.3%) i/s (216.66 ns/i) - 23.378M in 5.067600s | |
Comparison: | |
Cached ENV hash access: 14211933.1 i/s | |
credentials-style access: 4615607.5 i/s - 3.08x slower | |
ENV['KEY'] direct access: 1440994.2 i/s - 9.86x slower | |
ENV.fetch direct access: 1413890.8 i/s - 10.05x slower | |
Memory Usage: | |
============= | |
Calculating ------------------------------------- | |
ENV['KEY'] direct access | |
12.000k memsize ( 0.000 retained) | |
300.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
ENV.fetch direct access | |
12.000k memsize ( 0.000 retained) | |
300.000 objects ( 0.000 retained) | |
3.000 strings ( 0.000 retained) | |
Cached ENV hash access | |
0.000 memsize ( 0.000 retained) | |
0.000 objects ( 0.000 retained) | |
0.000 strings ( 0.000 retained) | |
credentials-style access | |
12.000k memsize ( 0.000 retained) | |
300.000 objects ( 0.000 retained) | |
0.000 strings ( 0.000 retained) | |
Comparison: | |
Cached ENV hash access: 0 allocated | |
ENV['KEY'] direct access: 12000 allocated - Infx more | |
ENV.fetch direct access: 12000 allocated - Infx more | |
credentials-style access: 12000 allocated - Infx more |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment