[rubygems/rubygems] Stop allocating the same settings keys repeatedly
Running `bundle update --bundler` on a rails app locally: ``` ==> memprof.after.txt <== Total allocated: 301.90 kB (3794 objects) Total retained: 73.24 kB (698 objects) ==> memprof.before.txt <== Total allocated: 14.47 MB (196378 objects) Total retained: 25.93 kB (202 objects) ``` So for a slight increase in retained memory (all keys are now retained), we go from about 200k allocations in the settings file to under 4k https://github.com/rubygems/rubygems/commit/e64debb6ae
This commit is contained in:
parent
4d86d932fd
commit
c423d6e0e4
@ -97,6 +97,8 @@ module Bundler
|
|||||||
|
|
||||||
@global_config = load_config(global_config_file)
|
@global_config = load_config(global_config_file)
|
||||||
@temporary = {}
|
@temporary = {}
|
||||||
|
|
||||||
|
@key_cache = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](name)
|
def [](name)
|
||||||
@ -312,7 +314,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def key_for(key)
|
def key_for(key)
|
||||||
self.class.key_for(key)
|
@key_cache[key] ||= self.class.key_for(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -344,12 +346,12 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_bool(name)
|
def is_bool(name)
|
||||||
name = name.to_s
|
name = self.class.key_to_s(name)
|
||||||
BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name))
|
BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_string(name)
|
def is_string(name)
|
||||||
name = name.to_s
|
name = self.class.key_to_s(name)
|
||||||
STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.")
|
STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -365,11 +367,11 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_num(key)
|
def is_num(key)
|
||||||
NUMBER_KEYS.include?(key.to_s)
|
NUMBER_KEYS.include?(self.class.key_to_s(key))
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_array(key)
|
def is_array(key)
|
||||||
ARRAY_KEYS.include?(key.to_s)
|
ARRAY_KEYS.include?(self.class.key_to_s(key))
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_credential(key)
|
def is_credential(key)
|
||||||
@ -392,7 +394,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def set_key(raw_key, value, hash, file)
|
def set_key(raw_key, value, hash, file)
|
||||||
raw_key = raw_key.to_s
|
raw_key = self.class.key_to_s(raw_key)
|
||||||
value = array_to_s(value) if is_array(raw_key)
|
value = array_to_s(value) if is_array(raw_key)
|
||||||
|
|
||||||
key = key_for(raw_key)
|
key = key_for(raw_key)
|
||||||
@ -412,7 +414,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def converted_value(value, key)
|
def converted_value(value, key)
|
||||||
key = key.to_s
|
key = self.class.key_to_s(key)
|
||||||
|
|
||||||
if is_array(key)
|
if is_array(key)
|
||||||
to_array(value)
|
to_array(value)
|
||||||
@ -472,17 +474,16 @@ module Bundler
|
|||||||
valid_file = file.exist? && !file.size.zero?
|
valid_file = file.exist? && !file.size.zero?
|
||||||
return {} unless valid_file
|
return {} unless valid_file
|
||||||
serializer_class.load(file.read).inject({}) do |config, (k, v)|
|
serializer_class.load(file.read).inject({}) do |config, (k, v)|
|
||||||
new_k = k
|
|
||||||
|
|
||||||
if k.include?("-")
|
if k.include?("-")
|
||||||
Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
|
Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
|
||||||
"This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
|
"This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
|
||||||
"Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
|
"Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
|
||||||
|
|
||||||
new_k = k.gsub("-", "___")
|
# string hash keys are frozen
|
||||||
|
k = k.gsub("-", "___")
|
||||||
end
|
end
|
||||||
|
|
||||||
config[new_k] = v
|
config[k] = v
|
||||||
config
|
config
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -512,7 +513,7 @@ module Bundler
|
|||||||
|
|
||||||
def self.key_for(key)
|
def self.key_for(key)
|
||||||
key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
|
key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
|
||||||
key = key.to_s.gsub(".", "__")
|
key = key_to_s(key).gsub(".", "__")
|
||||||
key.gsub!("-", "___")
|
key.gsub!("-", "___")
|
||||||
key.upcase!
|
key.upcase!
|
||||||
|
|
||||||
@ -536,5 +537,34 @@ module Bundler
|
|||||||
end
|
end
|
||||||
"#{prefix}#{uri}#{suffix}"
|
"#{prefix}#{uri}#{suffix}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is a hot method, so avoid respond_to? checks on every invocation
|
||||||
|
if :read.respond_to?(:name)
|
||||||
|
def self.key_to_s(key)
|
||||||
|
case key
|
||||||
|
when String
|
||||||
|
key
|
||||||
|
when Symbol
|
||||||
|
key.name
|
||||||
|
when Bundler::URI::HTTP
|
||||||
|
key.to_s
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Invalid key: #{key.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
def self.key_to_s(key)
|
||||||
|
case key
|
||||||
|
when String
|
||||||
|
key
|
||||||
|
when Symbol
|
||||||
|
key.to_s
|
||||||
|
when Bundler::URI::HTTP
|
||||||
|
key.to_s
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Invalid key: #{key.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,8 +54,8 @@ module Bundler
|
|||||||
str.split(/\r?\n/).each do |line|
|
str.split(/\r?\n/).each do |line|
|
||||||
if match = HASH_REGEX.match(line)
|
if match = HASH_REGEX.match(line)
|
||||||
indent, key, quote, val = match.captures
|
indent, key, quote, val = match.captures
|
||||||
key = convert_to_backward_compatible_key(key)
|
convert_to_backward_compatible_key!(key)
|
||||||
depth = indent.scan(/ /).length
|
depth = indent.size / 2
|
||||||
if quote.empty? && val.empty?
|
if quote.empty? && val.empty?
|
||||||
new_hash = {}
|
new_hash = {}
|
||||||
stack[depth][key] = new_hash
|
stack[depth][key] = new_hash
|
||||||
@ -76,14 +76,13 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
# for settings' keys
|
# for settings' keys
|
||||||
def convert_to_backward_compatible_key(key)
|
def convert_to_backward_compatible_key!(key)
|
||||||
key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z}
|
key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
|
||||||
key = key.gsub(".", "__") if key.include?(".")
|
key.gsub!(".", "__")
|
||||||
key
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
private :dump_hash, :convert_to_backward_compatible_key
|
private :dump_hash, :convert_to_backward_compatible_key!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,8 +54,8 @@ module Gem
|
|||||||
str.split(/\r?\n/).each do |line|
|
str.split(/\r?\n/).each do |line|
|
||||||
if match = HASH_REGEX.match(line)
|
if match = HASH_REGEX.match(line)
|
||||||
indent, key, quote, val = match.captures
|
indent, key, quote, val = match.captures
|
||||||
key = convert_to_backward_compatible_key(key)
|
convert_to_backward_compatible_key!(key)
|
||||||
depth = indent.scan(/ /).length
|
depth = indent.size / 2
|
||||||
if quote.empty? && val.empty?
|
if quote.empty? && val.empty?
|
||||||
new_hash = {}
|
new_hash = {}
|
||||||
stack[depth][key] = new_hash
|
stack[depth][key] = new_hash
|
||||||
@ -76,14 +76,13 @@ module Gem
|
|||||||
end
|
end
|
||||||
|
|
||||||
# for settings' keys
|
# for settings' keys
|
||||||
def convert_to_backward_compatible_key(key)
|
def convert_to_backward_compatible_key!(key)
|
||||||
key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z}
|
key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
|
||||||
key = key.gsub(".", "__") if key.include?(".")
|
key.gsub!(".", "__")
|
||||||
key
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
private :dump_hash, :convert_to_backward_compatible_key
|
private :dump_hash, :convert_to_backward_compatible_key!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user