mirror of
https://github.com/ruby/ruby.git
synced 2025-08-24 13:34:17 +02:00

My application spends more than 30% of time during `bundle update`
comparing versions due to versions being sorted inside
next_package_to_try. This has been addressed in pub_grub by defining a
strategy interface (a `#next_package_and_version` method) which allows
consumers to have finer control over the heuristic to select the next
package to try.
This commit implements the new strategy interface to remove extraneous
version sorting (previously in next_package_to_try) since only the final
count of versions is used.
Combined with a previous change to pub_grub (already applied to
Bundler), this commit results in `bundle update` taking only half the
time it did on 2.6.5.
62f69e27f0
40 lines
1 KiB
Ruby
40 lines
1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Bundler
|
|
class Resolver
|
|
class Strategy
|
|
def initialize(source)
|
|
@source = source
|
|
end
|
|
|
|
def next_package_and_version(unsatisfied)
|
|
package, range = next_term_to_try_from(unsatisfied)
|
|
|
|
[package, most_preferred_version_of(package, range).first]
|
|
end
|
|
|
|
private
|
|
|
|
def next_term_to_try_from(unsatisfied)
|
|
unsatisfied.min_by do |package, range|
|
|
matching_versions = @source.versions_for(package, range)
|
|
higher_versions = @source.versions_for(package, range.upper_invert)
|
|
|
|
[matching_versions.count <= 1 ? 0 : 1, higher_versions.count]
|
|
end
|
|
end
|
|
|
|
def most_preferred_version_of(package, range)
|
|
versions = @source.versions_for(package, range)
|
|
|
|
# Conditional avoids (among other things) calling
|
|
# sort_versions_by_preferred with the root package
|
|
if versions.size > 1
|
|
@source.sort_versions_by_preferred(package, versions)
|
|
else
|
|
versions
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|