Skip to content

Instantly share code, notes, and snippets.

@guiocavalcanti
Forked from ankane/README.md
Created November 2, 2013 16:45

Revisions

  1. guiocavalcanti revised this gist Nov 2, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ def pull(dep)

    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!
    # ActiveSupport::Autoload.eager_autoload!
    end
    end

  2. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -60,13 +60,13 @@ Here's what I did:
    ## Bonus

    ```sh
    time script/rails console # or server, etc
    script/rails console # or server, etc
    ```

    is faster than

    ```sh
    time bundle exec rails console
    bundle exec rails console
    ```

    Try it yourself
  3. @ankane ankane revised this gist Feb 24, 2013. 2 changed files with 5 additions and 5 deletions.
    9 changes: 5 additions & 4 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -21,19 +21,20 @@ tire 0.2592 2.9%
    Total 4.8583 100.0%
    ```

    Forked from [this awesome gist](https://gist.github.com/panthomakos/2588879) by [Pan Thomakos](https://github.com/panthomakos).
    Forked from [this awesome gist](https://gist.github.com/panthomakos/2588879) by [Pan Thomakos](https://github.com/panthomakos)

    ## Use it

    ```sh
    curl -fsSL https://gist.github.com/raw/5022636/benchmark.rb | ruby
    ```

    To only require certains groups (like Rails does), do
    To only require certain groups - like Rails does - do

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

    ## Now what?
    1 change: 0 additions & 1 deletion benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -99,4 +99,3 @@ def pull(dep)
    end
    puts line
    puts format % ["Total", total, 100]
    puts "\n\n"
  4. @ankane ankane revised this gist Feb 24, 2013. 2 changed files with 36 additions and 23 deletions.
    26 changes: 12 additions & 14 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,24 +1,22 @@
    # Benchmark.rb
    # Benchmark Bundler

    Because loading gems take longer than you think
    Because loading gems can take longer than you think

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

    Gem Time(sec) Pct %
    --------------------------------------------------
    jazz_hands 1.1986 12.6%
    mongoid 1.0774 11.4%
    fog 0.7371 7.8%
    newrelic_rpm 0.6181 6.5%
    ruby-prof 0.5841 6.2%
    debugger 0.3582 3.8%
    geocoder 0.3345 3.5%
    delayed_job 0.3147 3.3%
    bitly 0.2678 2.8%
    turbo-sprockets-rails3 0.2658 2.8%
    sass 0.2614 2.8%
    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%
    ```
    @@ -46,7 +44,7 @@ http://iain.nl/getting-the-most-out-of-bundler-groups

    ## The results

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

    Here's what I did:

    33 changes: 24 additions & 9 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -3,18 +3,20 @@
    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 = ENV["BUNDLE_GROUPS"].to_s.split(",")
    groups.map! { |g| g.to_sym }
    groups = [:default] if groups.empty?

    # taken from https://github.com/carlhuda/bundler/blob/v1.2.4/lib/bundler/runtime.rb
    def pull(dep)
    required_file = nil

    @@ -44,10 +46,13 @@ def pull(dep)
    end
    end

    dependencies = Bundler.setup.dependencies.map(&:name)
    # get list of gems

    dependencies = Bundler.setup.dependencies

    rails_included = dependencies.include?("rails")
    # include rails first if it exists

    rails_included = dependencies.map(&:name).include?("rails")
    if rails_included
    rails_time =
    Benchmark.realtime do
    @@ -59,29 +64,39 @@ def pull(dep)
    end
    end

    $VERBOSE = nil
    # time loads

    gems = {}

    Bundler.setup.dependencies.each do |dep|
    $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 "-"*50
    puts line
    gems.sort_by{|gem, time| time }.reverse.each do |gem, time|
    puts format % [gem, time, (time / total * 100)]
    end
    puts "-"*50
    puts "#{format}\n\n" % ["Total", total, 100]
    puts line
    puts format % ["Total", total, 100]
    puts "\n\n"
  5. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 73 additions and 0 deletions.
    73 changes: 73 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    # Benchmark.rb

    Because loading gems take longer than you think

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

    Gem Time(sec) Pct %
    --------------------------------------------------
    jazz_hands 1.1986 12.6%
    mongoid 1.0774 11.4%
    fog 0.7371 7.8%
    newrelic_rpm 0.6181 6.5%
    ruby-prof 0.5841 6.2%
    debugger 0.3582 3.8%
    geocoder 0.3345 3.5%
    delayed_job 0.3147 3.3%
    bitly 0.2678 2.8%
    turbo-sprockets-rails3 0.2658 2.8%
    sass 0.2614 2.8%
    --------------------------------------------------
    Total 4.8583 100.0%
    ```

    Forked from [this awesome gist](https://gist.github.com/panthomakos/2588879) by [Pan Thomakos](https://github.com/panthomakos).

    ## Use it

    ```sh
    curl -fsSL https://gist.github.com/raw/5022636/benchmark.rb | ruby
    ```

    To only require certains groups (like Rails does), do

    ```sh
    # Rails development default groups
    curl -fsSL https://gist.github.com/raw/5022636/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 reduced our 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

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

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

    1. Removed unused gems

    ## Bonus

    ```sh
    time script/rails console # or server, etc
    ```

    is faster than

    ```sh
    time bundle exec rails console
    ```

    Try it yourself
  6. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -7,10 +7,10 @@
    /^no such file to load -- (.+)$/i,
    /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
    /^Missing API definition file in (.+)$/i,
    /^cannot load such file -- (.+)$/i,
    /^cannot load such file -- (.+)$/i
    ]

    groups = ENV["BUNDLER_GROUPS"].to_s.split(",")
    groups = ENV["BUNDLE_GROUPS"].to_s.split(",")
    groups.map! { |g| g.to_sym }
    groups = [:default] if groups.empty?

  7. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 36 additions and 14 deletions.
    50 changes: 36 additions & 14 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,11 @@
    /^cannot load such file -- (.+)$/i,
    ]

    groups = ENV["BUNDLER_GROUPS"].to_s.split(",")
    groups.map! { |g| g.to_sym }
    groups = [:default] if groups.empty?

    # taken from https://github.com/carlhuda/bundler/blob/v1.2.4/lib/bundler/runtime.rb
    def pull(dep)
    required_file = nil

    @@ -28,7 +33,9 @@ def pull(dep)
    Kernel.require namespaced_file
    rescue LoadError
    REGEXPS.find { |r| r =~ e.message }
    raise if dep.autorequire || $1.gsub('-', '/') != namespaced_file
    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 }
    @@ -37,29 +44,44 @@ def pull(dep)
    end
    end

    rails_time =
    Benchmark.realtime do
    require 'rails/all'
    dependencies = Bundler.setup.dependencies.map(&:name)

    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!
    end
    rails_included = dependencies.include?("rails")

    if rails_included
    rails_time =
    Benchmark.realtime do
    require 'rails/all'

    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!
    end
    end

    $VERBOSE = nil

    gems = {}

    Bundler.load.setup(:default, :development, :assets).dependencies.each do |dependency|
    gems[dependency.name] = Benchmark.realtime{ pull(dependency) }
    putc "."
    Bundler.setup.dependencies.each do |dep|
    if ((dep.groups & groups).any? && dep.current_platform?)
    gems[dep.name] = Benchmark.realtime{ pull(dep) }
    putc "."
    end
    end
    puts
    puts "[DONE]\n\n"

    gems["rails"] = rails_time
    if rails_included
    gems["rails"] = rails_time
    end

    total = gems.map{|gem, time| time }.inject(0.0){|x, sum| sum + x }
    format = "%-30s %9.4f %8.1f%%"

    puts "%s %36s %9s" % ["Gem", "Time(sec)", "Pct %"]
    puts "-"*50
    gems.sort_by{|gem, time| time }.reverse.each do |gem, time|
    puts "%-30s %8.4f %6.1f%%" % [gem[0...30], time, (time / total * 100)]
    puts format % [gem, time, (time / total * 100)]
    end
    puts "-"*50
    puts "#{format}\n\n" % ["Total", total, 100]
  8. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -50,7 +50,7 @@ def pull(dep)

    gems = {}

    Bundler.setup.dependencies.each do |dependency|
    Bundler.load.setup(:default, :development, :assets).dependencies.each do |dependency|
    gems[dependency.name] = Benchmark.realtime{ pull(dependency) }
    putc "."
    end
  9. @ankane ankane revised this gist Feb 24, 2013. 1 changed file with 23 additions and 11 deletions.
    34 changes: 23 additions & 11 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,6 @@
    #!/usr/bin/env ruby

    require 'bundler/setup'
    require 'benchmark'

    REGEXPS = [
    @@ -36,18 +37,29 @@ def pull(dep)
    end
    end

    require 'rails/all'
    rails_time =
    Benchmark.realtime do
    require 'rails/all'

    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!
    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!
    end

    $VERBOSE = nil

    Benchmark.bm do |x|
    Bundler.setup.dependencies.each do |dependency|
    x.report(dependency.name[0..20].ljust(21)) do
    pull(dependency)
    end
    end
    end
    gems = {}

    Bundler.setup.dependencies.each do |dependency|
    gems[dependency.name] = Benchmark.realtime{ pull(dependency) }
    putc "."
    end
    puts

    gems["rails"] = rails_time

    total = gems.map{|gem, time| time }.inject(0.0){|x, sum| sum + x }

    gems.sort_by{|gem, time| time }.reverse.each do |gem, time|
    puts "%-30s %8.4f %6.1f%%" % [gem[0...30], time, (time / total * 100)]
    end
  10. @panthomakos panthomakos revised this gist May 14, 2012. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -38,6 +38,10 @@ def pull(dep)

    require 'rails/all'

    # If you would prefer gems to incur the cost of autoloading
    # Rails frameworks, then comment out this next line.
    ActiveSupport::Autoload.eager_autoload!

    $VERBOSE = nil

    Benchmark.bm do |x|
  11. @panthomakos panthomakos revised this gist May 10, 2012. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,8 @@
    ]

    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
  12. @panthomakos panthomakos created this gist May 3, 2012.
    47 changes: 47 additions & 0 deletions benchmark.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    #!/usr/bin/env ruby

    require 'benchmark'

    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,
    ]

    def pull(dep)
    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 }
    raise if dep.autorequire || $1.gsub('-', '/') != namespaced_file
    end
    else
    REGEXPS.find { |r| r =~ e.message }
    raise if dep.autorequire || $1 != required_file
    end
    end
    end

    require 'rails/all'

    $VERBOSE = nil

    Benchmark.bm do |x|
    Bundler.setup.dependencies.each do |dependency|
    x.report(dependency.name[0..20].ljust(21)) do
    pull(dependency)
    end
    end
    end