Skip to content

Instantly share code, notes, and snippets.

@asaaki
Last active July 6, 2020 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asaaki/affb6cdf9eb5533c93a44b3acb90518a to your computer and use it in GitHub Desktop.
Save asaaki/affb6cdf9eb5533c93a44b3acb90518a to your computer and use it in GitHub Desktop.
Ruby: Do ENV vars have a significant impact on the runtime performance?
#!/usr/bin/env ruby
# gem install benchmark-ips
require 'benchmark'
require 'benchmark/ips'
# https://github.com/evanphx/benchmark-ips#custom-suite
class GCSuite
def warming(*); run_gc; end
def running(*); run_gc; end
def warmup_stats(*); end
def add_report(*); end
private def run_gc
GC.enable
GC.start
GC.disable
end
end
SUITE = GCSuite.new
# ActiveSupport-like concern
module KlassyValue
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def set_class_value(v)
define_singleton_method(:classy_value) { v }
end
end
end
class KlassStatic
include KlassyValue
set_class_value('/usr/bin/fakeshell')
def result
self.class.classy_value
end
end
class KlassEnv
include KlassyValue
set_class_value(ENV['SHELL'])
def result
self.class.classy_value
end
end
class InstanceStatic
def initialize
@value = '/usr/bin/fakeshell'
end
def result
@value
end
end
class InstanceEnvInit
def initialize
@value = ENV['SHELL']
end
def result
@value
end
end
class InstanceEnvMethod
def result
ENV['SHELL']
end
end
class InstanceHashMethod
FAKE_ENV = { 'SHELL' => '/usr/bin/fakeshell' }
def result
FAKE_ENV['SHELL']
end
end
module Things
KlassStaticInstance = KlassStatic.new
KlassEnvInstance = KlassEnv.new
InstanceStaticInstance = InstanceStatic.new
InstanceEnvInitInstance = InstanceEnvInit.new
InstanceEnvMethodInstance = InstanceEnvMethod.new
InstanceHashMethodInstance = InstanceHashMethod.new
end
Benchmark.ips do |b|
include Things
b.config(suite: SUITE)
b.report('class_static-value') { KlassStaticInstance.result }
b.report('class_env-value') { KlassEnvInstance.result }
b.report('instance_static-value') { InstanceStaticInstance.result }
b.report('instance_env-value-init') { InstanceEnvInitInstance.result }
b.report('instance_env-value-imethod') { InstanceEnvMethodInstance.result }
b.report('instance_hash-value-imethod') { InstanceHashMethodInstance.result }
end
@asaaki
Copy link
Author

asaaki commented Jul 6, 2020

Warming up --------------------------------------
  class_static-value   825.405k i/100ms
     class_env-value   741.069k i/100ms
instance_static-value
                         1.855M i/100ms
instance_env-value-init
                         1.889M i/100ms
instance_env-value-imethod
                       335.657k i/100ms
instance_hash-value-imethod
                         1.257M i/100ms
Calculating -------------------------------------
  class_static-value      8.294M (± 3.9%) i/s -     42.096M in   5.084323s
     class_env-value      8.107M (± 8.1%) i/s -     40.759M in   5.065543s
instance_static-value
                         18.667M (± 1.9%) i/s -     94.589M in   5.068994s
instance_env-value-init
                         18.920M (± 1.7%) i/s -     96.315M in   5.092205s
instance_env-value-imethod
                          2.997M (±12.4%) i/s -     14.769M in   5.011458s
instance_hash-value-imethod
                         12.066M (± 8.5%) i/s -     60.337M in   5.043788s

The performance hit for the class vars comes from the lookup itself, but the ENV var is not re-read each time, of course.
Reading the hash-like ENV does come with a price compared to regular hashes, but is only significant in instance method calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment