Skip to content

Instantly share code, notes, and snippets.

@sunny
Created April 6, 2020 08:32
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 sunny/8a609a793dbf9f1c5883385049bae6aa to your computer and use it in GitHub Desktop.
Save sunny/8a609a793dbf9f1c5883385049bae6aa to your computer and use it in GitHub Desktop.
Show time to require each dependency in your application's Gemfile
require "benchmark"
require "rubygems"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __dir__)
require "bundler/setup"
# https://github.com/rubygems/rubygems/blob/a753447de8fb92dad30e927656984aa2b7765f3d/bundler/lib/bundler/runtime.rb#L46
REQUIRE_ERRORS = [
/^no such file to load -- (.+)$/i,
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
/^Missing API definition file in (.+)$/i,
/^cannot load such file -- (.+)$/i,
/^dlopen\([^)]*\): Library not loaded: (.+)$/i,
].freeze
def load_bundler_dependency(dep)
return unless dep.should_include?
required_file = nil
begin
# Loop through all the specified autorequires for the
# dependency. If there are none, use the dependency's name
# as the autorequire.
Array(dep.autorequire || dep.name).each do |file|
# Allow `require: true` as an alias for `require: <name>`
file = dep.name if file == true
required_file = file
begin
Kernel.require file
rescue RuntimeError => e
raise e if e.is_a?(LoadError) # we handle this a little later
raise Bundler::GemRequireError.new e,
"There was an error while trying to load the gem '#{file}'."
end
end
rescue LoadError => e
REQUIRE_ERRORS.find {|r| r =~ e.message }
raise if dep.autorequire || $1 != required_file
if dep.autorequire.nil? && dep.name.include?("-")
begin
namespaced_file = dep.name.tr("-", "/")
Kernel.require namespaced_file
rescue LoadError => e
REQUIRE_ERRORS.find {|r| r =~ e.message }
raise if $1 != namespaced_file
end
end
end
end
results = []
results << ["rails/all", Benchmark.measure { require "rails/all" }]
Bundler.setup(*Rails.groups).dependencies.map do |dep|
results << [dep.name, Benchmark.measure { load_bundler_dependency(dep) }]
end
results.sort_by { |dep, result| result.total }.each do |dep, result|
puts "%.5fs %s" % [result.total, dep]
end
puts "--------"
puts "%.5fs total" % results.sum { |_, result| result.total }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment