33

在 Ruby on Rails 中分析控制器操作的最佳方法是什么。目前,我正在使用蛮力方法在puts Time.now我认为会成为瓶颈的地方进行调用。但这感觉真的,真的很脏。必须有更好的方法。

4

5 回答 5

44

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

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

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

group :development do
    gem "ruby-prof"
end

然后在 ApplicationController 中添加一个环绕过滤器

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

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

于 2012-01-28T03:01:19.657 回答
9

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

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

于 2008-08-28T18:40:04.153 回答
9

使用 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中获得了这个例子的想法,它讨论了不同的测试类型和一些关于性能测试的内容。

于 2008-08-27T23:53:02.130 回答
1

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

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

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

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

于 2008-08-28T18:52:37.307 回答
-1

这适用于 Rails 4.2.6:

    o=OpenStruct.new(logger: Rails.logger)
    o.extend ActiveSupport::Benchmarkable
    o.benchmark 'name' do
      # ... your code ...
    end
于 2016-04-27T03:21:21.177 回答