剖析Ruby代码?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

除了ruby-prof和核心Benchmark类外,你用什么来分析你的Ruby代码?特别是,你如何找到代码中的瓶颈?它几乎感觉我需要使用我自己的小工具来确定所有时间都花在我的代码中。

我意识到ruby-prof提供了这个功能,但是输出结果非常混乱,并且很难找出你自己代码的哪个块是问题的根源(它告诉你哪些方法调用花费的时间最多虽然)。所以我并没有真正想要那么多,也没有真正能够利用它。

提问于
用户回答回答于

假设要找到“瓶颈”,你必须以某种方式进行大量测量是非常自然的。几乎所有的剖析器都基于它,这是很自然的。

实际上,寻找和测量不是同一个问题。测量是需要看看你发现(和固定)是否有所不同。对我而言,寻找解决办法更像调试而非测量。

解释它的最简单的方法是从一个无限循环或接近无限循环开始。你是怎么找到它的?你暂停它,看看堆栈,对吧?因为你知道问题在堆栈中的某处。只需暂停一次,然后需要研究堆栈中的代码。如果你想确定你找到它,暂停几次。

假设代码只需要两倍的时间。这意味着当你暂停时,有50%的机会会看到它做不必要的事情。如果你暂停一下并观察它10次,你会在大约5次的动作中捕捉到它。事实上,只要你看到它做了一些你可以优化的样本少至2个,你就发现了一个“瓶颈”。修复它,测量加速,显示它并重复。

即使你最大的问题不是很大,这个方法最终会找到它。此外,还有一种放大现象,在删除大型问题后,小问题变得更容易找到。这可以让你继续下去,直到代码接近最佳。

PS:完成此操作后,可能仍有机会加速。例如,优化算法可能取决于数值稳定性。消息驱动体系结构可能会使跟踪代码执行的原因变得更加困难。在实时软件中,性能问题可能只是偶尔发生,并且不太容易采样。这需要更聪明。重新开始测量并没有做到这一点。

用户回答回答于

下面是一个关于如何使用它的快速解决方案:安装gem:gem install stackprof...。在代码中添加:require 'stackprof'并将想要检查的部分包围如下:

StackProf.run(mode: :cpu, out: 'stackprof-output.dump') do {YOUR_CODE} end

运行ruby脚本之后,可以在终端中使用stackprof stackprof.dump:

Mode: cpu(1000)
Samples: 9145 (1.25% miss rate)
GC: 448 (4.90%)

 TOTAL    (pct)     SAMPLES    (pct)     FRAME
   236   (2.6%)         231   (2.5%)     String#blank?
   546   (6.0%)         216   (2.4%)     ActiveRecord::ConnectionAdapters::Mysql2Adapter#select
   212   (2.3%)         199   (2.2%)     Mysql2::Client#query_with_timing
   190   (2.1%)         155   (1.7%)     ERB::Util#html_escape``

在这里,可以看到需要大量时间的所有方法。现在最棒的部分是:钻进去stackprof stackprof.dump --method String#blank?然后得到特定方法的输出:

String#blank? (lib/active_support/core_ext/object/blank.rb:80)
  samples:   231 self (2.5%)  /    236 total (2.6%)
  callers:
    112  (   47.5%)  Object#present?
  code:
                                  |    80  |   def blank?
  187    (2.0%) /   187   (2.0%)  |    81  |     self !~ /[^[:space:]]/
                                  |    82  |   end

而且,可以很容易地确定代码的哪一部分需要大量时间来运行。

如果想获得可视化输出,请执行以下操作stackprof stackprof.dump --graphviz >> stackprof.dot并使用Graphviz(brew install graphviz)dot- T pdf -o stackprof.pdf stackprof.dot获得一个漂亮的PDF输出,它突出显示了需要很长时间才能运行的方法。

扫码关注云+社区