2012-04-06 24 views
2

如何让ActiveSupport::TimeWithZone更快地构建或懒惰?使Rails中的TimeWithZone对象变懒惰

我一直在分析我的Rails应用程序,我发现cpu时间的三分之一用于构建这些TimeWithZone对象。我凭我的智慧结束了这一切。看起来简单的时间对象如何构造起来可能如此昂贵?

这里是每个请求运行bazillion倍的代码:

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) 

有没有什么,我可以做的,以编程方式取代所有模型的日期时间属性与懒惰TimeWithZone对象是普通的旧(和便宜的)Time对象,直到他们在哪个时间被使用,变成TimeWithZone对象?这远远超出了我的Ruby能力。

+0

生产模式 – guidoism 2012-04-06 03:10:59

+0

您的基准测试在我的笔记本电脑上给出了相当不同的结果(Thinkpad Ubuntu 11.10 Ruby 1.9.3 p125,Rails 3.2.3)。我几乎在同一时间看到#at方法和#in_time_zone。您的代码的结果:Time.at:0.060000 0.000000 0.060000(0.054021); Time.at.in_time_zone:0.120000 0.000000 0.120000(0.115737) – joelparkerhenderson 2012-04-06 06:09:32

回答

0

这个问题让我感到震惊的是,您正在关注的代码是从deserialize_from_cache(json)内部调用的。为什么那么被这么频繁地调用?您是否可以再看看调用链,看看您是否可以减少json-to-time解析的数量?