Skip to content

Instantly share code, notes, and snippets.

@bensheldon
Created July 28, 2025 16:57
Show Gist options
  • Save bensheldon/ea85f7f4836942c55fb362048f4202ed to your computer and use it in GitHub Desktop.
Save bensheldon/ea85f7f4836942c55fb362048f4202ed to your computer and use it in GitHub Desktop.
# Benchmark performance differences between "require" and "Autoload"
#
# $ for run in {1..3}; do ZEITWERK=0 AUTOLOAD=0 ruby scripts/autoload.rb && ZEITWERK=0 AUTOLOAD=1 ruby scripts/autoload.rb; done
# REQUIRE 0.208000 0.360310 0.568310 ( 0.568952)
# AUTOLOAD 0.242265 0.374332 0.616597 ( 0.617540)
# REQUIRE 0.214861 0.360820 0.575681 ( 0.576603)
# AUTOLOAD 0.225601 0.364912 0.590513 ( 0.590673)
# REQUIRE 0.214296 0.359103 0.573399 ( 0.574008)
# AUTOLOAD 0.224972 0.359481 0.584453 ( 0.584926)
# $ for run in {1..3}; do ZEITWERK=1 AUTOLOAD=0 ruby scripts/autoload.rb && ZEITWERK=1 AUTOLOAD=1 ruby scripts/autoload.rb; done
# REQUIRE(Z) 0.240464 0.364613 0.605077 ( 0.605292)
# AUTOLOAD(Z) 0.280514 0.380929 0.661443 ( 0.671503)
# REQUIRE(Z) 0.251022 0.377413 0.628435 ( 0.631271)
# AUTOLOAD(Z) 0.271090 0.376573 0.647663 ( 0.656937)
# REQUIRE(Z) 0.250157 0.375761 0.625918 ( 0.629233)
# AUTOLOAD(Z) 0.272919 0.377538 0.650457 ( 0.651376)
require 'benchmark'
require "tmpdir"
CONST_COUNT = 10_000
tmpdir = Dir.mktmpdir
const_names = []
CONST_COUNT.times do |n|
const_name = :"M#{n}"
File.write(tmpdir + "/#{const_name}.rb", <<~RUBY)
module Namespace
module #{const_name}
def self.property=(value)
@property = value
end
end
end
RUBY
const_names << const_name
end
File.write(tmpdir + "/namespace_require.rb", <<~RUBY)
#{const_names.map { |const_name| "require '#{tmpdir}/#{const_name}.rb'" }.join("\n")}
module Namespace
end
#{const_names.map { |const_name| "Namespace::#{const_name}.property = true" }.join("\n")}
RUBY
File.write(tmpdir + "/namespace_autoload.rb", <<~RUBY)
module Namespace
#{const_names.map { |const_name| "autoload :#{const_name}, '#{tmpdir}/#{const_name}.rb'" }.join("\n")}
end
#{const_names.map { |const_name| "Namespace::#{const_name}.property = true" }.join("\n")}
RUBY
AUTOLOAD = ENV["AUTOLOAD"] == "1"
ZEITWERK = ENV["ZEITWERK"] == "1"
if ZEITWERK
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'zeitwerk'
end
Zeitwerk::Loader.new.setup
end
if AUTOLOAD
puts "AUTOLOAD#{ZEITWERK ? "(Z)" : ""}" + Benchmark.measure { require tmpdir + "/namespace_autoload.rb" }.to_s
else
puts "REQUIRE#{ZEITWERK ? "(Z)" : ""}" + Benchmark.measure { require tmpdir + "/namespace_require.rb" }.to_s
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment