Ruby Profiler详解之stackprof

简介

stackprof 是基于采样的一个调优工具,采样有什么好处呢?好处就是你可以线上使用,按照内置的算法抓取一部分数据,只影响一小部分性能。它会产生一系列的 dump 文件,然后你在线下分析这些文件,从而定位出问题,google有一篇基于采样的论文,也基本证明了采样是可行的。而 stackprof 也是深受 google 的 perftools 的影响,采用了采样的方式来做调优。

基本使用方法

StackProf.run(mode: :cpu, out: ‘./stackprof.dump‘) do
  # 你的代码
end

这里我们给出一段示例代码,来作为测试目标:

require "stackprof"

class Compute

  def m1
    "string" * 100
  end

  def m2
    "string" * 10000
  end

  def start
    100_000.times do
      m1
      m2
    end
  end
end

StackProf.run(mode: :cpu, out: ‘./stackprof.dump‘) do
  Compute.new.start
end

保存为test.rb,同时执行 ruby test.rb 就会在当前目录下生成 stackprof.dump 文件,我们用 stackprof 打开这个文件:

stackprof stackprof.dump --text
==================================
  Mode: cpu(1000)
  Samples: 1793 (0.61% miss rate)
  GC: 587 (32.74%)
==================================
     TOTAL    (pct)     SAMPLES    (pct)     FRAME
      1106  (61.7%)        1106  (61.7%)     Compute#m2
        98   (5.5%)          98   (5.5%)     Compute#m1
      1206  (67.3%)           2   (0.1%)     block in Compute#start
      1206  (67.3%)           0   (0.0%)     <main>
      1206  (67.3%)           0   (0.0%)     Compute#start
      1206  (67.3%)           0   (0.0%)     <main>
      1206  (67.3%)           0   (0.0%)     block in <main>

这里可以很明显的看出是 m2 方法比较慢,占据了大部分的执行时间,相比其他的调优工具,它只是列出了用户自己的方法所占时间比,在 ruby-prof 中的测试中,它是会显示String#*这个方法的占比的,但是对于我们来说,它的意义不大,而 stackprof 是不会理会标准库里的方法的。同时 stackprof 也是可以过滤方法的,比如我们发现了 m2 这个方法有问题,那么就可以把它过滤出来,看看细节:

stackprof stackprof.dump --text --method ‘Compute#m2‘

Compute#m2 (/Users/lizhe/Workspace/ruby-performance-tuning/test.rb:9)
  samples:  1106 self (61.7%)  /   1106 total (61.7%)
  callers:
    1106  (  100.0%)  block in Compute#start
  code:
                                  |     9  |   end
 1106   (61.7%) /  1106  (61.7%)  |    10  |
                                  |    11  |   def start

我们可以看到 m2 这个方法定义在哪一个文件的哪一行,同时是谁调用了它,以及还显示了它在源码中的上下文。假如有多个方法调用了 m2 ,还会显示出这几个方法,以及他们调用 m2 所占的比例,也就是上面的 callers 部分,因为只有一个 start 方法调用了 m2,所以它是 100% 。

在rack中的使用方法

stackprof 本身实现了一个 rack middleware ,所以可以很方便的挂载到一个 rack 应用中:

use StackProf::Middleware, enabled: true, mode: :cpu, save_every: 5

在 rails 中使用,先在 Gemfile 中添加 stackprof ,然后添加 middleware :

config.middleware.use StackProf::Middleware, enabled: true, mode: :cpu, save_every: 5

然后请求你的应用,多请求几次,每5秒钟它会保存一次输出结果到tmp目录中,查看其中某一个结果:

==================================
  Mode: cpu(1000)
  Samples: 155 (0.00% miss rate)
  GC: 11 (7.10%)
==================================
     TOTAL    (pct)     SAMPLES    (pct)     FRAME
        18  (11.6%)          18  (11.6%)     Hike::Index#entries
        12   (7.7%)          12   (7.7%)     Hike::Index#stat
         9   (5.8%)           9   (5.8%)     #<Module:0x007fb72a0c7b08>.load_with_autoloading
        18  (11.6%)           9   (5.8%)     Sprockets::Cache::FileStore#[]
         6   (3.9%)           6   (3.9%)     block (2 levels) in BindingOfCaller::BindingExtensions#callers
         5   (3.2%)           5   (3.2%)     Time.parse
         5   (3.2%)           5   (3.2%)     Sprockets::Mime#mime_types
         5   (3.2%)           5   (3.2%)     Pathname#chop_basename
         4   (2.6%)           4   (2.6%)     block in ActionView::PathResolver#find_template_paths
         4   (2.6%)           4   (2.6%)     block in BetterErrors::ExceptionExtension#set_backtrace
        15   (9.7%)           3   (1.9%)     block in ActiveSupport::Dependencies#load_file
         2   (1.3%)           2   (1.3%)     Temple::Mixins::CompiledDispatcher::DispatchNode#initialize
         5   (3.2%)           2   (1.3%)     ActionDispatch::Cookies::EncryptedCookieJar#initialize
         2   (1.3%)           2   (1.3%)     ActiveSupport::KeyGenerator#generate_key
         2   (1.3%)           2   (1.3%)     block in ActionView::PathResolver#query
         4   (2.6%)           2   (1.3%)     Slim::Parser#initialize
       113  (72.9%)           2   (1.3%)     ActionView::Renderer#render_template
         2   (1.3%)           2   (1.3%)     Hike::Trail#stat
         2   (1.3%)           2   (1.3%)     block in ActiveSupport::Dependencies#search_for_file
        22  (14.2%)           2   (1.3%)     block in Temple::Filters::MultiFlattener#on_multi
        20  (12.9%)           2   (1.3%)     Temple::Filters::ControlFlow#dispatcher
        15   (9.7%)           2   (1.3%)     ActionView::Renderer#render_partial
         1   (0.6%)           1   (0.6%)     block in Slim::Parser#initialize
         1   (0.6%)           1   (0.6%)     Pathname#prepend_prefix
         1   (0.6%)           1   (0.6%)     String#blank?
         1   (0.6%)           1   (0.6%)     ActiveSupport::SafeBuffer#initialize
        10   (6.5%)           1   (0.6%)     Sprockets::Asset#dependency_fresh?
         1   (0.6%)           1   (0.6%)     Sprockets::Asset#init_with
         1   (0.6%)           1   (0.6%)     Hike::Index#sort_matches
         1   (0.6%)           1   (0.6%)     block in ActiveSupport::Dependencies::Loadable#require

可以利用这样的方式调试线上的环境。

参考链接:

——
本文系OneAPM工程师原创文章。OneAPM是中国基础软件领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和SQL语句的实时抓取。想阅读更多技术文章,请访问OneAPM官方技术博客

时间: 07-06

Ruby Profiler详解之stackprof的相关文章

Ruby Profiler详解之ruby-prof(I)

项目地址: ruby-prof 在上一篇 Ruby 中的 Profiling 工具中,我们列举了几种最常用的 Profiler,不过只是简单介绍,这一次详细介绍一下 ruby-prof 的使用方法. ruby-prof 是比较强大的,支持 cpu,内存使用,对象分配等等的性能分析,而且提供了很多友好的输出格式,不仅仅是有基于文字,html 的格式,还能输出 graphviz 格式的 dot 文件,以及适用与 KCacheGrind 的call tree格式, 其实这个格式是基于 Valgrind

Ruby Gem命令详解

转自:http://www.jianshu.com/p/728184da1699 Gem介绍: Gem是一个管理Ruby库和程序的标准包,它通过Ruby Gem(如 http://rubygems.org/ )源来查找.安装.升级和卸载软件包,非常的便捷. Ruby 1.9.2版本默认已安装Ruby Gem,如果你使用其它发行版本,请参考“如何安装Ruby Gem”. Ruby gem包的安装方式: 所有的gem包,会被安装到 /[Ruby root]/lib/ruby/gems/[ver]/

iOS开发——实用篇&amp;KVO与KVC详解

KVO与KVC详解 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听(KVO)特性: 键值编码KVC 键值监听KVO 键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Valu

支撑5亿用户、1.5亿活跃用户的Twitter最新架构详解及相关实现

如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 摘要:Twitter出道之初只是个奋斗在RoR上的小站点,而如今已拥有1.5亿的活跃用户,系统日传输tweet更多达4亿条,并已完成了以服务为核心的系统架构蜕变. Twitter如今在世界范围内已拥有1.5亿的活跃用户,为了给用户生成timeline(时间轴)需支撑30万QPS,其firehose每秒同样生成22MB数据.整个系统每天传输tweet 4亿条,并且只需要5分钟就可以让一条twe

linux下easy_install的安装与使用详解

Python中的easy_install工具用起来非常好用,它的作用类似于Php中的pear,或者Ruby中的gem,或者Perl中的cpan. 1.easy_install安装 如果想使用easy_install工具,需要先安装setuptools,不过更酷的方法是使用ez_setup.py脚本:执行如下命令: 1 2 shell#  wget -q http://peak.telecommunity.com/dist/ez_setup.py shell#  python ez_setup.p

触碰jQuery:AJAX异步详解

触碰jQuery:AJAX异步详解 传送门:异步编程系列目录…… 示例源码:触碰jQuery:AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1)   使用CSS和XHTML来表示. 2)   使用DOM模型来交互和动态显示. 3)   使用XMLHttpRequest来和服务器进行异步通信. 4)   使用javascript来绑定和调用.

Console命令详解,让调试js代码变得更简单

Firebug是网页开发的利器,能够极大地提升工作效率. 但是,它不太容易上手.我曾经翻译过一篇<Firebug入门指南>,介绍了一些基本用法.今天,继续介绍它的高级用法. =================================== Firebug控制台详解 作者:阮一峰出处:http://www.ruanyifeng.com/blog/2011/03/firebug_console_tutorial.html 控制台(Console)是Firebug的第一个面板,也是最重要的面板

Windows渗透利器之Pentest BOX使用详解(一)

内容概览:                                     知识科普                                    优缺点总结 功能参数详解翻译: 控制台参数详解翻译 setting各项功能参数翻译详解: 基本设置(含外观,字体,标签栏等设置) 启动设置(含任务栏其他等) 特征 综合参数 宏设置 文本管理器 基础信息 知识科普: Pentest Box在2015年发布,具体月份不详.Pentest Box开源项目的创始人是Aditya Agrawa

高并发高流量网站架构详解

(推荐)高并发高流量网站架构详解 Web2.0的兴起,掀起了互联网新一轮的网络创业大潮.以用户为导 向的新网站建设概念,细分了网站功能和用户群,不仅成功的造就了一大批新生的网站,也极大的方便了上网的人们.但Web2.0以用户为导向的理念,使得新 生的网站有了新的特点--高并发,高流量,数据量大,逻辑复杂等,对网站建设也提出了新的要求. 本文围绕高并发高流量的网站架构设计问题,主要研究讨论了以下内容: 首先在整个网络的高度讨论了使用镜像网站,CDN内容分发网络等技术对负载均衡带来的便利及各自的优缺

Python对Excel操作详解

  Python对Excel操作详解 文档摘要: 本文档主要介绍如何通过python对office excel进行读写操作,使用了xlrd.xlwt和xlutils模块.另外还演示了如何通过Tcl  tcom包对excel操作. 关键字: Python.Excel.xlrd.xlwt.xlutils.TCl.tcom     1 Python简介 Python是一种面向对象.直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务.