提交 1bf50bad 编写于 作者: S schneems

Decrease string allocations in apply_inflections

In `apply_inflections` a string is down cased and some whitespace stripped in the front (which allocate strings). This would normally be fine, however `uncountables` is a fairly small array (10 elements out of the box) and this method gets called a TON. Instead we can keep an array of valid regexes for each uncountable so we don't have to allocate new strings.

This change buys us 325,106 bytes of memory and 3,251 fewer objects per request.
上级 f80aa599
......@@ -27,6 +27,37 @@ module Inflector
class Inflections
@__instance__ = ThreadSafe::Cache.new
class Uncountables < Array
def initialize
@regex_array = []
super
end
def delete(entry)
super entry
@regex_array.delete(to_regex(entry))
end
def <<(*word)
add(word)
end
def add(words)
self.concat(words.flatten.map(&:downcase))
@regex_array += self.map {|word| to_regex(word) }
self
end
def uncountable?(str)
@regex_array.detect {|regex| regex.match(str) }
end
private
def to_regex(string)
/\b#{::Regexp.escape(string)}\Z/i
end
end
def self.instance(locale = :en)
@__instance__[locale] ||= new
end
......@@ -34,7 +65,7 @@ def self.instance(locale = :en)
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
def initialize
@plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
@plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], Uncountables.new, [], {}, /(?=a)b/
end
# Private, for the test suite.
......@@ -160,7 +191,7 @@ def irregular(singular, plural)
# uncountable 'money', 'information'
# uncountable %w( money information rice )
def uncountable(*words)
@uncountables += words.flatten.map(&:downcase)
@uncountables.add(words)
end
# Specifies a humanized form of a string by a regular expression rule or
......@@ -185,7 +216,7 @@ def human(rule, replacement)
def clear(scope = :all)
case scope
when :all
@plurals, @singulars, @uncountables, @humans = [], [], [], []
@plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
else
instance_variable_set "@#{scope}", []
end
......
......@@ -354,7 +354,7 @@ def ordinalize(number)
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
# const_regexp("::") # => "::"
def const_regexp(camel_cased_word) #:nodoc:
parts = camel_cased_word.split("::")
parts = camel_cased_word.split("::".freeze)
return Regexp.escape(camel_cased_word) if parts.blank?
......@@ -372,7 +372,7 @@ def const_regexp(camel_cased_word) #:nodoc:
def apply_inflections(word, rules)
result = word.to_s.dup
if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
if word.empty? || inflections.uncountables.uncountable?(result)
result
else
rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册