Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only loop over spec dependencies to resolve conflicts #842

Merged
merged 1 commit into from
Mar 13, 2014

Commits on Mar 5, 2014

  1. only loop over spec dependencies to resolve conflicts

    Before this commit, the `conflicts` method would loop over every
    activated gem and the `conflicts` method would get slower as you
    activate more gems.
    
    This commit speeds up the `conflicts` method which is called on ever gem
    activation by only looping over dependencies on the spec itself, then
    looking up possible conflicts from the loaded_specs hash.
    
    Here is the benchmark:
    
    ```ruby
    def util_spec name, version = 2
      spec = Gem::Specification.new do |s|
        s.platform    = Gem::Platform::RUBY
        s.name        = name
        s.version     = version
        s.author      = 'A User'
        s.email       = 'example@example.com'
        s.homepage    = 'http://example.com'
        s.summary     = "this is a summary"
        s.description = "This is a test description"
      end
    
      spec.loaded_from = spec.spec_file
    
      Gem::Specification.add_spec spec
    
      return spec
    end
    
    require 'benchmark/ips'
    
    (ENV['N'] || 100).to_i.times { |i| util_spec(i.to_s).activate }
    
    p Gem.loaded_specs.size
    
    Benchmark.ips do |x|
      spec = util_spec 'a'
      # Typical mode, runs the block as many times as it can
      x.report("conflicts") { spec.conflicts }
    end
    ```
    
    Before my change:
    
    ```
    [aaron@higgins rubygems (master)]$ N=100 ruby -I lib test.rb
    101
    Calculating -------------------------------------
               conflicts      1957 i/100ms
    -------------------------------------------------
               conflicts    20090.1 (±4.6%) i/s -     101764 in   5.077002s
    [aaron@higgins rubygems (master)]$ N=1000 ruby -I lib test.rb
    1001
    Calculating -------------------------------------
               conflicts       214 i/100ms
    -------------------------------------------------
               conflicts     2209.6 (±5.0%) i/s -      11128 in   5.050977s
    ```
    
    After my change:
    
    ```
    [aaron@higgins rubygems (master)]$ N=100 ruby -I lib test.rb
    101
    Calculating -------------------------------------
               conflicts     71357 i/100ms
    -------------------------------------------------
               conflicts  2230414.4 (±7.2%) i/s -   11131692 in   5.022458s
    [aaron@higgins rubygems (master)]$ N=1000 ruby -I lib test.rb
    1001
    Calculating -------------------------------------
               conflicts     69479 i/100ms
    -------------------------------------------------
               conflicts  2171237.1 (±6.2%) i/s -   10838724 in   5.013410s
    ```
    
    You can see that after this change the speed of `conflicts` stays about
    the same regardless of the number of specs loaded.
    tenderlove committed Mar 5, 2014
    Configuration menu
    Copy the full SHA
    3e6cd47 View commit details
    Browse the repository at this point in the history