carlhuda/bundler — pull request #2181 by cheald (2012-11-24 04:18:20+00:00)
Title: Performance improvements

After running ruby-prof around bundler a few times, I noticed that it was spending a lot of time in `LazySpecification#==` and `LockfileParser#parse_spec`. This patch is just a simple refactoring of those two sticky spots to be faster. Additionally, I moved constant strings and regexes into constants to avoid extraneous per-line garbage generation when parsing a lockfile.

* `LazySpecification` now has an `#identifier` method that is a memoized hash value of the name, version, source, platform, and dependencies. This gives us a quick way to effectively test `eql?`, which has implications in various places.
* `LazySpecification#==` now uses `#identifier` rather than building and doing array comparisons.
* `LockfileParser` accumulates specs into a hash keyed by `#identifier` rather than testing `@specs.include?` for every spec. This reduces the runtime from O(n^2) to O(n log n).

All specs pass under Ruby 1.9.3-p327.

To demonstrate the impact, here's my before-and-after times for a production bundle:

Before (sec) After (sec) % of original
bundle install 1.22 0.89 72.95%
bundle check 0.57 0.31 54.39%
bundle list 0.65 0.38 58.46%