@@ -55,14 +55,9 @@ def versions_etag_path
5555 end
5656
5757 def checksums
58- checksums = { }
59-
60- lines ( versions_path ) . each do |line |
61- name , _ , checksum = line . split ( " " , 3 )
62- checksums [ name ] = checksum
58+ lines ( versions_path ) . each_with_object ( { } ) do |line , checksums |
59+ parse_version_checksum ( line , checksums )
6360 end
64-
65- checksums
6661 end
6762
6863 def dependencies ( name )
@@ -106,6 +101,20 @@ def parse_gem(line)
106101 @dependency_parser . parse ( line )
107102 end
108103
104+ # This is mostly the same as `split(" ", 3)` but it avoids allocating extra objects.
105+ # This method gets called at least once for every gem when parsing versions.
106+ def parse_version_checksum ( line , checksums )
107+ line . freeze # allows slicing into the string to not allocate a copy of the line
108+ name_end = line . index ( " " )
109+ checksum_start = line . index ( " " , name_end + 1 ) + 1
110+ checksum_end = line . size - checksum_start
111+ # freeze name since it is used as a hash key
112+ # pre-freezing means a frozen copy isn't created
113+ name = line [ 0 , name_end ] . freeze
114+ checksum = line [ checksum_start , checksum_end ]
115+ checksums [ name ] = checksum
116+ end
117+
109118 def info_roots
110119 [
111120 directory . join ( "info" ) ,
0 commit comments