分析 rails 控制器操作

Profile a rails controller action

提问人:salt.racer 提问时间:8/28/2008 最后编辑:atwsalt.racer 更新时间:7/23/2019 访问量:12688

问:

在 Ruby on Rails 中分析控制器操作的最佳方式是什么?目前,我正在使用蛮力方法,在我认为会成为瓶颈的地方之间抛出调用。但那感觉真的非常非常肮脏。必须有更好的方法。puts Time.now

Ruby-on-Rails 红宝石

评论


答:

9赞 Chris Bunch 8/28/2008 #1

使用 Benchmark 标准库和 Rails 中提供的各种测试(单元、功能、集成)。下面是一个示例:

def test_do_something
  elapsed_time = Benchmark.realtime do
    100.downto(1) do |index|
      # do something here
    end
  end
  assert elapsed_time < SOME_LIMIT
end

因此,在这里,我们只做 100 次,通过 Benchmark 库对其进行计时,并确保它花费的时间少于SOME_LIMIT。

您可能还会发现以下链接很有用:Benchmark.realtime 参考和 Test::Unit 参考。另外,如果你喜欢“读书”,我从Agile Web Development with Rails中学到了这个例子的想法,它讨论了不同的测试类型和一些性能测试。

评论

3赞 Jon Bright 7/20/2010
这个答案告诉你如何确保你的操作运行得足够快。它对分析没有帮助,即找出操作的哪一部分花费的时间最多。
9赞 Stuart 8/29/2008 #2

有一个关于分析的 Railscast,非常值得一看

http://railscasts.com/episodes/98-request-profiling

1赞 John Topley 8/29/2008 #3

您可能想尝试一下 FiveRuns TuneUp 服务,因为它确实令人印象深刻。免责声明:我与 FiveRuns 没有任何关联,我刚刚尝试过这项服务。

TuneUp 是一项免费服务,您可以通过它下载一个插件,当您运行应用程序时,它会在屏幕顶部注入一个面板,该面板可以展开以显示详细的性能指标。

它为您提供了一些漂亮的图表,包括一个显示模型、视图和控制器所花费时间的比例的图表。如果需要,您甚至可以向下钻取以查看 ActiveRecord 正在执行的各个 SQL 查询,并且它可以通过再次单击向您显示基础数据库架构。

最后,您可以选择将分析数据上传到 FiveRuns 网站,以进行社区性能分析和建议。

评论

4赞 mrzasa 12/27/2012
链接已断开(DNS 已过期)。
44赞 Rob Davis 1/28/2012 #4

不久前,我学会了这种技术,发现它非常方便。

当它就位时,您可以添加到任何命中控制器的 URL。您的操作将照常运行,但它不会将呈现的页面交付给浏览器,而是发送一个详细的、格式良好的 ruby-prof 页面,显示您的操作花费时间的位置。?profile=true

首先,将 ruby-prof 添加到您的 Gemfile 中,可能在开发组中:

group :development do
    gem "ruby-prof"
end

然后向 ApplicationController 添加一个 around 筛选器

around_action :performance_profile if Rails.env == 'development'

def performance_profile
  if params[:profile] && result = RubyProf.profile { yield }

    out = StringIO.new
    RubyProf::GraphHtmlPrinter.new(result).print out, :min_percent => 0
    self.response_body = out.string

  else
    yield
  end
end

阅读 ruby-prof 的输出是一门艺术,但我会把它作为一种练习。

ScottJShea的补充说明:如果要更改测量类型,请放置以下位置:

RubyProf.measure_mode = RubyProf::GC_TIME #example

在应用程序控制器的 profile 方法之前。您可以在 ruby-prof 页面上找到可用测量值的列表。在撰写本文时,和数据流似乎已损坏(请参阅缺陷)。ifmemoryallocations

评论

5赞 Pavling 9/23/2012
对于任何需要粘贴此内容的人,您还需要在 ApplicationController 的顶部添加“require 'ruby-prof'”。另外,对我来说,我不得不将“self.response_body=”更改为“self.response.body=”(Rails 2.3.14)
0赞 Rob Davis 9/24/2012
感谢您的调整。 在 Rails 3.0 中添加。如果你使用的是 bundler,你不需要 ruby-prof,但我很高兴这种技术非常适用于旧版本的 Rails。response_body
0赞 jsarma 5/29/2013
谢谢你的提示,铺路。我也在使用 rails 2.3.14,但无法让它工作。无论我安装什么版本的 ruby-prof,我在 graph_html_printer.rb:98:in 'full_name' 中都收到“错误的参数数(0 表示 1)”。知道是什么原因造成的吗?
1赞 Leo 12/16/2014
若要覆盖 JSON、XML 等的返回格式,请将以下内容添加到 if 语句中:headers["Content-Type"] = "text/html"
-1赞 Minqi Pan 4/27/2016 #5

这在 Rails 4.2.6 中有效:

    o=OpenStruct.new(logger: Rails.logger)
    o.extend ActiveSupport::Benchmarkable
    o.benchmark 'name' do
      # ... your code ...
    end

评论

0赞 juliangonzalez 10/30/2018
这不会在日志或其他地方显示任何内容。