分析Ruby代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分析Ruby代码相关的知识,希望对你有一定的参考价值。

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

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

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

答案

很多分析师都是这样的。你需要知道的不是程序花费时间的地方,而是原因。 Any references on Dynamic Code Analysis?

ADDED:Here's how我在代码中发现了“瓶颈”。 (我讨厌这个词。)Here's a list的原因。

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

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

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

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

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

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

另一答案

要真正深入研究您的代码,请尝试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

以上是关于分析Ruby代码的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段

ruby Ruby片段

使用标准库Ruby将数据标记到Elasticsearch批量中

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段

Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段

gitlab 9.0对ruby的版本有要求吗