Skip to content

Instantly share code, notes, and snippets.

@tmm1
Created June 30, 2010 03:12
Show Gist options
  • Save tmm1/458185 to your computer and use it in GitHub Desktop.
Save tmm1/458185 to your computer and use it in GitHub Desktop.
performance improvements for Bundler and Gem::Version#<=>
require 'rubygems'
# diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb
# index 50d8204..4962ce1 100644
# --- a/lib/rubygems/version.rb
# +++ b/lib/rubygems/version.rb
# @@ -295,12 +295,16 @@ class Gem::Version
# rhsize = other.segments.size
# limit = (lhsize > rhsize ? lhsize : rhsize) - 1
#
# + lhsegments = segments
# + rhsegments = other.segments
# +
# 0.upto(limit) do |i|
# - lhs, rhs = segments[i] || 0, other.segments[i] || 0
# + lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
#
# + next if lhs == rhs
# return -1 if String === lhs && Numeric === rhs
# return 1 if Numeric === lhs && String === rhs
# - return lhs <=> rhs if lhs != rhs
# + return lhs <=> rhs
# end
#
# return 0
class Gem::FastVersion < Gem::Version
def <=> other
return 1 unless other # HACK: comparable with nil? why?
return nil unless self.class === other
lhsize = segments.size
rhsize = other.segments.size
limit = (lhsize > rhsize ? lhsize : rhsize) - 1
lhsegments = segments
rhsegments = other.segments
0.upto(limit) do |i|
lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
next if lhs == rhs
return -1 if String === lhs && Numeric === rhs
return 1 if Numeric === lhs && String === rhs
return lhs <=> rhs
end
return 0
end
end
class Gem::FasterVersion < Gem::FastVersion
def <=> other
return 0 if version == other.version
super
end
end
require 'version_sorter' # http://github.com/defunkt/version_sorter
class Gem::CExtVersion < Gem::Version
def <=> other
return 1 unless other # HACK: comparable with nil? why?
return nil unless self.class === other
return 0 if version == other.version
# XXX: this does not follow rubygems' prelease versioning rules
VersionSorter.sort([version, other.version]).first == version ?
-1 :
1
end
end
require 'benchmark'
Benchmark.bmbm do |b|
[ Gem::Version, Gem::FastVersion, Gem::FasterVersion, Gem::CExtVersion ].each do |klass|
b.report klass.to_s do
a = klass.new('3.0.0.0.0')
b = klass.new('3.0.0.0.0')
c = klass.new('3.0.0.0.3')
250_000.times do
a <=> b
b <=> c
end
end
end
end
__END__
Rehearsal ------------------------------------------------------
Gem::Version 10.630000 0.020000 10.650000 ( 10.731254)
Gem::FastVersion 7.270000 0.010000 7.280000 ( 7.359935)
Gem::FasterVersion 4.370000 0.010000 4.380000 ( 4.408528)
Gem::CExtVersion 3.520000 0.010000 3.530000 ( 3.540201)
-------------------------------------------- total: 25.840000sec
user system total real
Gem::Version 11.430000 0.020000 11.450000 ( 11.513403)
Gem::FastVersion 7.230000 0.010000 7.240000 ( 7.313092)
Gem::FasterVersion 4.450000 0.010000 4.460000 ( 4.478300)
Gem::CExtVersion 3.500000 0.010000 3.510000 ( 3.539400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment