【问题标题】:Ruby 1.9 slower than Ruby 1.8?Ruby 1.9 比 Ruby 1.8 慢?
【发布时间】:2010-10-22 13:24:31
【问题描述】:

我有一个 Rails 2.3.8 应用程序,该应用程序从数据库中提取大量数据并使用 300-600 个部分进行渲染(递归渲染树型结构)。对一个请求进行基准测试使我的响应时间约为 7 秒。

我认为将我的 Ruby 版本从 1.8 升级到 1.9 会给我带来性能提升,但是当我对 1.9 版本进行基准测试时,我得到了大约 9 秒的响应时间(比 1.8 慢 2 秒)。这让我很惊讶。

哪些因素会导致 Ruby 1.9 的执行速度比 Ruby 1.8 慢?

以下是日志文件的一部分。

红宝石 1.8

Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (4.6ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.7ms)
Rendered family_index/descendants/_descendant (4.7ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (4.5ms)
Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (37.9ms)
Rendered family_index/surname_groups/_pedigree (3162.9ms)
Rendered shared/_headers (4.6ms)
Rendered shared/_new_messages (0.6ms)
Rendered shared/_home_logo (1.1ms)
Rendered shared/_login_box (4.0ms)
Rendered shared/_navigation (13.6ms)
Rendered shared/_flash_messages (0.8ms)
Rendered shared/_footer (1.0ms)
Rendered shared/_analytics (0.8ms)
Completed in 4552ms (View: 3352, DB: 147) | 200 OK [http://localhost/family_index/surname_groups/31]

红宝石 1.9

Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (1.9ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.4ms)
Rendered family_index/descendants/_descendant (2.0ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (1.9ms)
Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (15.1ms)
Rendered family_index/surname_groups/_pedigree (762.8ms)
Rendered shared/_headers (2.6ms)
Rendered shared/_new_messages (0.7ms)
Rendered shared/_home_logo (0.9ms)
Rendered shared/_login_box (3.6ms)
Rendered shared/_navigation (7.3ms)
Rendered shared/_flash_messages (0.7ms)
Rendered shared/_footer (0.8ms)
Rendered shared/_analytics (0.6ms)
Completed in 5736ms (View: 942, DB: 128) | 200 OK [http://localhost/family_index/surname_groups/31]

看起来 Ruby 1.9 渲染视图和处理数据库的速度更快,但完成请求的速度仍然较慢。

Ruby 1.8:

Completed in 4552ms (View: 3352, DB: 147) | 200 OK [http://localhost/family_index/surname_groups/31]

Ruby 1.9:

Completed in 5736ms (View: 942, DB: 128) | 200 OK [http://localhost/family_index/surname_groups/31]

2010 年 10 月 26 日更新

我在我的代码中发现了瓶颈。它来自使用延迟加载关联加载大量 ActiveRecord 项目的行。数据库时间很小,但我猜所有的对象分配都会造成损失。这是我的协会:

has_many  :deep_branches,
            :class_name => "FamilyIndex::Branch",
            :include => {
              :descendant => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
                :children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
                  :children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
                    :children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference] # add marriages to this data
                  }]
                }]
              }]
            }

如果不进行预先加载,完成操作大约需要 40 秒才能完成,因此使用 :include 可以将性能提高约 10 倍。仍在寻找一种方法来加快这一进程。也许缓存是唯一的出路。

【问题讨论】:

  • 取决于您的代码。你的代码是什么,你可以说是否有瓶颈
  • 总的来说,ruby 1.9 在性能方面已经提升了很多。我认为您需要显示一些代码。
  • 太多代码无法发布,但我相信 sepp2k 的回复指出了我的性能问题的很大一部分。
  • 300 个部分,它是 7 秒?我的页面有 50 个部分,每页需要 30 到 40 秒!我不知道是SASS总是编译.sass文件还是JS文件被合并为一个,甚至是一些sleep语句。但是 45 秒是相当长的。

标签: ruby-on-rails ruby performance ruby-1.9


【解决方案1】:

1.9 可能比 1.8 慢的一个领域是字符串处理。

由于 1.9 具有适当的 unicode 支持索引或切片,因此 unicode 编码的字符串可能比 1.8 中花费更长的时间,因为在 1.8 中 string[i] 将只返回 ith 字节,而在 1.9 中它必须经过字符串来查找ith 字符。

如果您进行大量字符串处理并且不需要适当的 unicode 支持,您可以将编码设置为 ASCII 或可能的二进制,这将大大加快字符串处理速度。

【讨论】:

  • 我打赌就是这样。我正在进行很多字符串拆分操作,这肯定会影响性能。我不需要 unicode 支持,所以我将编码设置为 ASCII 看看会发生什么。
  • @Jimmy,请报告您的发现。
  • 我检查了app的编码,编码是US-ASCII,所以我不认为是我之前怀疑的编码问题。如果有帮助,我会从我的日志文件中添加一些摘录。
  • @JimmyZ:你是在开发模式下运行 rails 吗?您是否也查看过生产模式下的性能?我想 Rails 在开发模式下的自动重新加载对于 1.9 来说会是很多开销。
  • 我在开发模式下运行。我已经更改了一些设置以更像 prod 模式(如自动重新加载)运行,但它似乎没有任何区别。也许详细的日志记录会增加足够的开销。让我尝试在生产模式下运行它。
【解决方案2】:

因此,我的请求处理时间最长的领域是通过 ActiveRecord 的延迟急切加载的大量数据(请参阅问题中列出的关联)。我对 ActiveRecord 2.3.8 的内部结构不够熟悉,所以最终我不确定是什么导致了“缓慢”。

我最终完成了我自己的急切加载类型——在一个查询中获取所有人员记录,在一个查询中获取所有状态,以及我需要的其他关联对象,将它们放在一个哈希中,然后将它们拼接到它们的树结构中.

这大大提高了性能,将请求时间缩短到 1-1.5 秒。改进有利于在 1.8 和 1.9 中运行的应用程序,现在我的应用程序在 1.9 中运行速度更快。

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-06
    • 2012-03-30
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多