Skip to content

Instantly share code, notes, and snippets.

@assembler
Forked from ankane/README.md
Last active December 20, 2015 11:09
Show Gist options
  • Save assembler/6121664 to your computer and use it in GitHub Desktop.
Save assembler/6121664 to your computer and use it in GitHub Desktop.

Rails 4 fork

Benchmark Bundler

Because loading gems can take longer than you think

$ curl -fsSL https://gist.github.com/raw/6121664/benchmark.rb | ruby
............................................................[DONE]

Gem                            Time(sec)     Pct %
--------------------------------------------------
rails                             2.4161     26.9%
mongoid                           0.9279     10.3%
fog                               0.7707      8.6%
newrelic_rpm                      0.5839      6.5%
geocoder                          0.3578      4.0%
delayed_job                       0.3162      3.5%
bitly                             0.2703      3.0%
sass                              0.2651      3.0%
tire                              0.2592      2.9%
--------------------------------------------------
Total                             4.8583    100.0%

Forked from this awesome gist by Pan Thomakos

Use it

curl -fsSL https://gist.github.com/raw/6121664/benchmark.rb | ruby

To only require certain groups - like Rails does - do

# default rails development groups
curl -fsSL https://gist.github.com/raw/6121664/benchmark.rb | \
BUNDLE_GROUPS=default,development,assets ruby

Now what?

Read this article

http://iain.nl/getting-the-most-out-of-bundler-groups

The results

I was able to reduce gem load time from 12.1 seconds to 6.7 seconds - over 5 seconds!

Here's what I did:

  1. Added :console group like the article above suggested

  2. Commented out ruby-prof, oink, and debugger when not in use

  3. Moved newrelic_rpm and turbo-sprockets-rails3 to :staging, :production groups

  4. Removed unused gems

Bonus

script/rails console # or server, etc

is faster than

bundle exec rails console

Try it yourself

#!/usr/bin/env ruby
require 'bundler/setup'
require 'benchmark'
groups = ENV["BUNDLE_GROUPS"].to_s.split(",")
# taken from https://github.com/carlhuda/bundler/blob/v1.2.4/lib/bundler/runtime.rb
REGEXPS = [
/^no such file to load -- (.+)$/i,
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
/^Missing API definition file in (.+)$/i,
/^cannot load such file -- (.+)$/i
]
groups.map! { |g| g.to_sym }
groups = [:default] if groups.empty?
def pull(dep)
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|
required_file = file
Kernel.require file
end
rescue LoadError => e
if dep.autorequire.nil? && dep.name.include?('-')
begin
namespaced_file = dep.name.gsub('-', '/')
Kernel.require namespaced_file
rescue LoadError
REGEXPS.find { |r| r =~ e.message }
regex_name = $1
raise if dep.autorequire || (regex_name && regex_name.gsub('-', '/') != namespaced_file)
raise e if regex_name.nil?
end
else
REGEXPS.find { |r| r =~ e.message }
raise if dep.autorequire || $1 != required_file
end
end
end
# get list of gems
dependencies = Bundler.setup.dependencies
# include rails first if it exists
rails_included = dependencies.map(&:name).include?("rails")
if rails_included
rails_time =
Benchmark.realtime do
require 'rails/all'
end
end
# time loads
gems = {}
$VERBOSE = nil
dependencies.each do |dep|
if ((dep.groups & groups).any? && dep.current_platform?)
gems[dep.name] = Benchmark.realtime{ pull(dep) }
putc "."
end
end
puts "[DONE]\n\n"
# set real rails gem load time
if rails_included
gems["rails"] = rails_time
end
# calculate total for percentages
total = gems.map{|gem, time| time }.inject(0.0){|x, sum| sum + x }
# output results
format = "%-30s %9.4f %8.1f%%"
line = "-"*50
puts "%s %36s %9s" % ["Gem", "Time(sec)", "Pct %"]
puts line
gems.sort_by{|gem, time| time }.reverse.each do |gem, time|
puts format % [gem, time, (time / total * 100)]
end
puts line
puts format % ["Total", total, 100]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment