【问题标题】:Ruby on Rails: serialize Hash incredibly slowRuby on Rails:序列化哈希非常慢
【发布时间】:2012-10-28 20:27:21
【问题描述】:

我有一个名为“Search”的简单模型,用于存储搜索。它捕获 URL 参数并将它们存储在属性 :search_criteria 中,该属性被序列化为哈希:

serialize :search_criteria, Hash

这一切都很完美,但它的表现很糟糕。仅针对 5 个对象,以下语句大约需要 0.2 秒。

start = Time.now
SavedSearch.all.map(&:search_criteria)
puts Time.now - start

但是,如果我删除了序列化行(这样 search_criteria 返回一个字符串),则语句只需要 0.002 秒。这是反序列化哈希的 2 个数量级的差异!

这里发生了什么?

Rails.version = 3.2.8 Ruby 1.9.3p194(2012-04-20 修订版 35410)[x86_64-linux]

【问题讨论】:

  • HashWithIndifferentAccess一样吗?
  • 不重启控制台多次重复测试是否一样?
  • 是的。每次运行都完全相同:比不调用序列化慢 2 个数量级。
  • 有人能重现这个吗?
  • 我在多个系统上又试了一次,到处都是一样的。谁能证实这一点?

标签: ruby-on-rails ruby serialization hash


【解决方案1】:

Active Record 可能会产生大量开销,因此看起来有点矫枉过正。当它循环时,它会实例化 SavedSearch 中的每个对象,然后评估它需要创建的属性,然后执行映射。

如果您知道确切的结构,它似乎存储在“search_criteria”中,那么只需将其存储在 YAML 中的文本属性中。那应该会快很多。

【讨论】:

  • 两个版本都在实例化 SavedSearch,但在一种情况下,我删除了“serialize :search_criteria, Hash”行。所以瓶颈似乎在于Hash的反序列化,而不是DB对象的实例化。
【解决方案2】:

问题是由 YAML 解析器引起的。反序列化 YAML 非常慢。我通过将 search_criteria 哈希序列化为 JSON 而不是 YAML 解决了这个问题。它现在快了大约 100 倍。

有关其他阅读材料,请查看http://iprog.com/posting/2009/10/ruby-on-rails-performance-series-intro-yaml

【讨论】:

  • 请注意,JSON 有缺点,例如不支持符号和其他一些特定于 ruby​​ 的对象。
  • 此外,如果性能是一个问题,您应该问自己为什么要使用序列化属性。您可能应该将其提取到一个单独的数据库模型中,或者使用 PostgreSQL 的 hstore 扩展,它支持在 postgres 中的键值存储。您还可以编写一个不选择您的序列化属性的范围。然后,当您不需要该属性时,您可以使用该范围,AR 应该比任何其他解决方案都要快。
猜你喜欢
  • 2012-01-28
  • 2014-04-09
  • 2010-12-29
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 2012-05-28
  • 2014-09-08
  • 1970-01-01
相关资源
最近更新 更多