为什么参数化在第一次执行时会非常慢

时间:2019-07-23 21:59:46

标签: ruby-on-rails ruby

我有以下代码,基本上将参数化的执行时间乘以

require 'active_support'
require 'active_support/core_ext'

for x in 0..10
  ss = Array.new(1000, "Book Author Title")
  st = Time.now
  ss = ss.map {|s| s.parameterize}
  et = Time.now
  p "parameterize 1000 simple strings takes #{'%.4f' % ((et - st)*1000)} milliseconds"
end
# p ss

但是我得到了输出,例如:

"parameterize 1000 simple strings takes 219.5780 milliseconds"
"parameterize 1000 simple strings takes 74.3870 milliseconds"
"parameterize 1000 simple strings takes 73.9830 milliseconds"
"parameterize 1000 simple strings takes 76.3160 milliseconds"
"parameterize 1000 simple strings takes 65.7620 milliseconds"
"parameterize 1000 simple strings takes 78.5280 milliseconds"
"parameterize 1000 simple strings takes 89.2950 milliseconds"
"parameterize 1000 simple strings takes 90.6750 milliseconds"
"parameterize 1000 simple strings takes 93.8500 milliseconds"
"parameterize 1000 simple strings takes 74.2330 milliseconds"
"parameterize 1000 simple strings takes 86.2160 milliseconds"

第一次执行它的成本要比以下高得多,我想知道为什么会这样。

谢谢大家!

1 个答案:

答案 0 :(得分:2)

简短答案:    ActiveSupport :: Inflector#parametrize的首次调用最终加载了Unicode数据库here。这会增加70毫秒以上的开销,这也是首次调用较慢的主要原因。

详细答案: 由于以下原因,"Book Author Title”.parametrize的第一次调用很慢:

  1. 加载unicode数据库并进行规范化需要70多个 毫秒
  2. 第一次调用时,
  3. I18n.transliterate(“ Book Author Title”)转换10-15毫秒并缓存响应。随后的调用返回缓存的值,该值需要0.002毫秒。

以下是加载unicode数据库的调用顺序:

ActiveSupport::Inflector.parametrize ->
 ActiveSupport::Inflector.transliterate ->
  ActiveSupport::Multibyte::Unicode.normalize ->
   https://github.com/rails/rails/blob/v5.2.3/activesupport/lib/active_support/multibyte/unicode.rb#L340

请尝试以下代码段进行验证。

require 'active_support'
require 'active_support/core_ext'
def benchmark_normalize(s)
  st = Time.now
  ts = ActiveSupport::Multibyte::Unicode.normalize(s, :c)
  et = Time.now
  p "takes #{'%.4f' % ((et - st)*1000)} milliseconds"
end
benchmark_normalize("Book Author Title")