分析Ruby代码

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

我意识到ruby-prof提供了这个,但输出坦率地说非常混乱,并且不容易找出你自己的代码的哪些实际块是问题的根源(它告诉你哪些方法调用占用了最多的时间)虽然)。 所以我并没有像我想的那样得到更多的东西,而且还没有真正能够利用它。

也许我做错了? 还有替代品吗? 谷歌搜索不会为我带来任何东西。

很多分析师都是这样的。 你需要知道的不是程序花费时间的地方,而是原因 。 有关动态代码分析的任何参考?

补充: 这是我在代码中找到“瓶颈”的方法。 (我讨厌这个词。) 这是一个原因列表 。

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

实际上,查找和测量不是同一个问题。 需要进行测量以确定您发现(和修复)的内容是否有所不同。 对我而言,找到解决方法更像是调试而不是测量。

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

假设代码只需要两倍的时间。 这意味着当你暂停它时,你有50%的机会看到它做了不必要的事情。 如果你暂停它并观察它10次,你将在行为中大约抓到它5次。 事实上,只要你看到它做了什么就可以在2个样本上进行优化,你就找到了“瓶颈”。 修复它,测量加速,显示它,然后重复。

即使你最大的问题不是很大,这种方法最终会找到它。 此外,还有放大现象,在您移除较大的问题后,小问题变得更容易找到。 这允许您继续前进,直到代码几乎达到最佳状态。

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

要真正深入研究您的代码,请尝试使用stackprof 。

以下是如何使用它的快速解决方案:安装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 graphvizdot- T pdf -o stackprof.pdf stackprof.dot获得漂亮的PDF输出,其中突出显示需要很长时间才能运行的方法。

这是我自己的问题,但我找到了一个非常惊人的分析工具,我必须在这里添加它:

http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler

与查看回溯相比,Flamegraphs使性能问题的根源非常明显

还有ruby -rprofile或同等地来自Ruby源代码, require 'profile'

文档:

https://ruby-doc.org/stdlib-2.1.0/libdoc/profiler/rdoc/Profiler__.html

Interesting Posts