diff options
author | Samuel Giddins <[email protected]> | 2023-09-18 18:51:15 -0700 |
---|---|---|
committer | git <[email protected]> | 2023-12-11 23:14:58 +0000 |
commit | 505715ddf17e004d184c0b71afb40a31e2e8c98e (patch) | |
tree | 483d4f9f86cf2628d822e4c0b6ce0c76e478524a /lib/rubygems/package/tar_header.rb | |
parent | 4a94ce8569c9399bd286d943ff35f6f3a25ed1b6 (diff) |
[rubygems/rubygems] Fewer allocations in gem installation
For now, on a small rails app I have hanging around:
```
==> memprof.after.txt <==
Total allocated: 872.51 MB (465330 objects)
Total retained: 40.48 kB (326 objects)
==> memprof.before.txt <==
Total allocated: 890.79 MB (1494026 objects)
Total retained: 40.40 kB (328 objects)
```
Not a huge difference in memory usage, but it's a drastic improvement
in total number of allocations.
Additionally, this will pay huge dividends once
https://github.com/ruby/zlib/pull/61 is merged, as it will allow us to
completely avoid allocations in the repeated calls to readpartial,
which currently accounts for most of the memory usage shown above.
https://github.com/rubygems/rubygems/commit/f78d45d927
Diffstat (limited to 'lib/rubygems/package/tar_header.rb')
-rw-r--r-- | lib/rubygems/package/tar_header.rb | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb index 7deafa994f..087f13f6c9 100644 --- a/lib/rubygems/package/tar_header.rb +++ b/lib/rubygems/package/tar_header.rb @@ -127,7 +127,8 @@ class Gem::Package::TarHeader end def self.strict_oct(str) - return str.strip.oct if /\A[0-7]*\z/.match?(str.strip) + str.strip! + return str.oct if /\A[0-7]*\z/.match?(str) raise ArgumentError, "#{str.inspect} is not an octal string" end @@ -137,7 +138,8 @@ class Gem::Package::TarHeader # \ff flags a negative 256-based number # In case we have a match, parse it as a signed binary value # in big-endian order, except that the high-order bit is ignored. - return str.unpack("N2").last if /\A[\x80\xff]/n.match?(str) + + return str.unpack1("@4N") if /\A[\x80\xff]/n.match?(str) strict_oct(str) end @@ -149,21 +151,23 @@ class Gem::Package::TarHeader raise ArgumentError, ":name, :size, :prefix and :mode required" end - vals[:uid] ||= 0 - vals[:gid] ||= 0 - vals[:mtime] ||= 0 - vals[:checksum] ||= "" - vals[:typeflag] = "0" if vals[:typeflag].nil? || vals[:typeflag].empty? - vals[:magic] ||= "ustar" - vals[:version] ||= "00" - vals[:uname] ||= "wheel" - vals[:gname] ||= "wheel" - vals[:devmajor] ||= 0 - vals[:devminor] ||= 0 - - FIELDS.each do |name| - instance_variable_set "@#{name}", vals[name] - end + @checksum = vals[:checksum] || "" + @devmajor = vals[:devmajor] || 0 + @devminor = vals[:devminor] || 0 + @gid = vals[:gid] || 0 + @gname = vals[:gname] || "wheel" + @linkname = vals[:linkname] + @magic = vals[:magic] || "ustar" + @mode = vals[:mode] + @mtime = vals[:mtime] || 0 + @name = vals[:name] + @prefix = vals[:prefix] + @size = vals[:size] + @typeflag = vals[:typeflag] + @typeflag = "0" if @typeflag.nil? || @typeflag.empty? + @uid = vals[:uid] || 0 + @uname = vals[:uname] || "wheel" + @version = vals[:version] || "00" @empty = vals[:empty] end |