在Rails中使TimeWithZone对象变得懒惰

时间:2012-04-06 00:36:46

标签: ruby performance profiling

如何让ActiveSupport::TimeWithZone更快地构建或延迟?

我一直在分析我的Rails应用程序,并且我发现构建这些TimeWithZone对象花费了三分之一的cpu时间。我的智慧结束了。怎么可能看似简单的时间对象构建起来如此昂贵?

以下是每个请求运行数十亿次的代码:

def deserialize_from_cache(json)
  attributes = ActiveSupport::JSON.decode(json)
  attributes.keys.to_a.each do |k|
    v = attributes[k]
    if v.is_a? Array and v.length == 2 and v[0] == 'Time'
      attributes[k] = Time.at(v[1]).in_time_zone # This is the expensive code
    end
  end
  self.allocate.init_with('attributes' => attributes)
end

我对普通的旧Time对象构造进行了基准测试,发现它比TimeWithZone构造快了一个数量级:

puts Benchmark.measure { 200000.times { Time.at(1330367843) } }
  0.070000   0.000000   0.070000 (  0.068956)

puts Benchmark.measure { 200000.times { Time.at(1330367843).in_time_zone } }
  0.720000   0.000000   0.720000 (  0.715802)

我能做些什么来以编程方式将所有模型的datetime属性替换为惰性TimeWithZone对象,这些对象是普通的(和便宜的)Time对象,直到它们被使用为止变成了TimeWithZone个对象?这远远超出了我的Ruby能力。

1 个答案:

答案 0 :(得分:0)

关于这个问题让我印象深刻的是你正在关注的代码是从deserialize_from_cache(json)内调用的。为什么 经常被调用?你是否可以进一步调查调用链,看看你是否可以减少json-to-time解析的数量?