Last active
July 6, 2020 11:14
-
-
Save asaaki/affb6cdf9eb5533c93a44b3acb90518a to your computer and use it in GitHub Desktop.
Ruby: Do ENV vars have a significant impact on the runtime performance?
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 | |
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.