Brief introduction
Stackprof is a sampling-based tuning tool, what are the benefits of sampling? The advantage is that you can use it online and grab part of the data based on the built-in algorithm, affecting only a fraction of the performance. It generates a series of dump files, and then you analyze the files online to locate the problem, and Google has a sample based paper that basically proves that sampling is feasible. And Stackprof is also deeply influenced by Google's perftools, using the sampling method to do the tuning.
Basic Use Method
StackProf.run(mode: :cpu, out: ‘./stackprof.dump‘) do # 你的代码end
Here we give a sample code to test the target:
require "stackprof"class Compute def m1 "string" * 100 end def m2 "string" * 10000 end def start 100_000.times do m1 m2 end endendStackProf.run(mode: :cpu, out: ‘./stackprof.dump‘) do Compute.new.startend
Save As test.rb
, while executing Ruby TEST.RB will generate the Stackprof.dump file in the current directory, we open this file with 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>
Here it can be clearly seen that the M2 method is relatively slow, occupy most of the execution time, compared to other tuning tools, it just lists the user's own method of the time ratio, in the ruby-prof test, it will show the String#*
proportion of this method, but for us, it is not very meaningful , and Stackprof is not going to ignore the methods in the standard library. At the same time Stackprof can also filter the method, for example, we found M2 This method has a problem, then you can filter it out to see the details:
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
We can see M2 This method defines which row of the file, and who is calling it, and also shows its context in the source code. If more than one method calls the M2, it also shows these methods, and the proportion they call M2, which is the callers part above, because only one start method calls M2, so it is 100%.
How to use in rack
The stackprof itself implements a rack middleware, so it can be conveniently mounted to a rack application:
use StackProf::Middleware, enabled: true, mode: :cpu, save_every: 5
To use in rails, first add stackprof to Gemfile and then add Middleware:
config.middleware.use StackProf::Middleware, enabled: true, mode: :cpu, save_every: 5
Then request your app, request a few more times, every 5 seconds it will save the output to the TMP directory to see one of the results:
================================== mode:cpu (+) samples:155 (0.00% miss Rate) gc:11 (7.1%) ======================= =========== 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::P athresolver#find_template_paths 4 (2.6%) 4 (2.6%) block in Bettererrors::exceptionextension#set_backtrace 15 (9.7%) 3 (1.9%) block in Activesupport::D ependencies#load_file 2 (1.3%) 2 (1.3%) Temple::mixins::compileddispatcher::D ispatchnode#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::P athresolver#query 4 (2.6%) 2 (1.3%) Slim::P arser#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::D ependencies#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::P arser#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::D ependencies::loadable#require
You can use this method to debug your online environment.
Reference Links:
- Https://github.com/tmm1/stackprof
——
This article is a ONEAPM engineer original article. ONEAPM is the emerging leader in China's basic software industry, helping enterprise users and developers easily implement slow program code and real-time crawling of SQL statements. To read more technical articles, please visit the ONEAPM Official technology blog.
Stackprof of Ruby Profiler