Ruby Profiler 详解之 stackprof - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OneAPM
V2EX    Ruby on Rails

Ruby Profiler 详解之 stackprof

  •  9
     
  •   OneAPM 2015-07-09 16:07:40 +08:00 3648 次点击
    这是一个创建于 3752 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简介

    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官方技术博客

    1 条回复    2016-10-04 18:25:15 +08:00
    venson
        1
    venson  
       2016-10-04 18:25:15 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4614 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 10:01 PVG 18:01 LAX 03:01 JFK 06:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86