bundler/bundler — pull request #3204 by dubek (2014-10-07 19:04:58+00:00)
Title: Setup performance improvements

# Overview

This PR includes two commits with two (unrelated) performance improvements for the setup process (which is executed during `bundle exec` or `require "bundler/setup"`). The first commit memoizes expensive calls to `expand_path` in Source::Path, and the second commit pre-calculates which gems are prereleases (which is an expensive call during the resolve process).

# How to reproduce?

## Setup

Create `prepare_libs.rb` in an empty dir:

```
require 'fileutils'
(1..100).each { |i|
FileUtils.mkdir_p("mylib#{i}/lib")
File.open("mylib#{i}/mylib#{i}-1.0.gemspec", "w") { |f|
f.puts <<-EOS
Gem::Specification.new do |s|
s.name = "mylib#{i}"
s.version = "1.0"
s.summary = ""
s.authors = ["me@example.com"]
end
EOS
}
File.open("mylib#{i}/lib/mylib#{i}.rb", "w") { |f|
f.puts "# dummy"
}
}
```

Create this `Gemfile` in the same dir:

```
(1..100).each do |i|
gem "mylib#{i}", :path => "mylib#{i}", :require => false
end
```

And now run:

```
ruby prepare_libs.rb
bundle install
```

## Measure

Bundler 1.7.3:

```
$ time bundle exec ruby -v -e 'puts 42'
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
42

real	0m5.799s
user	0m5.725s
sys	0m0.070s
```

Bundler with the suggested patches:

```
$ time dbundle exec ruby -v -e 'puts 42'
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
42

real	0m0.795s
user	0m0.740s
sys	0m0.053s
```

I experience 7X faster start-up time with the fixes (for this specific scenario of 100 local (Path) gems).