Basic memory profiling setup.
This makes it a bit easier to profile memory usage of certain components and plot them using Gnuplot. In the past I would write one-off scripts for this and throw them away, only to figure out I needed them again later on. Profiling samples are written to profile/samples and can be plotted using corresponding Gnuplot scripts found in profile/plot. The latter requires Gnuplot to be installed.
This commit is contained in:
parent
70fcc8534c
commit
53c45c621b
|
@ -7,3 +7,6 @@ lib/oga/xml/lexer.rb
|
|||
lib/oga/xml/parser.rb
|
||||
|
||||
benchmark/fixtures/big.xml
|
||||
|
||||
profile/samples/*.txt
|
||||
profile/samples/lexer/*.txt
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
require_relative '../profile_helper'
|
||||
|
||||
xml = read_big_xml
|
||||
lexer = Oga::XML::Lexer.new(xml)
|
||||
|
||||
profile_memory('lexer/big_xml')
|
||||
|
||||
lexer.advance { |tok| }
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env gnuplot
|
||||
|
||||
set title "Lexing 10MB of XML"
|
||||
|
||||
set xlabel "Sample"
|
||||
set ylabel "Memory (MB)"
|
||||
|
||||
set yrange [0:*]
|
||||
|
||||
set term qt persist
|
||||
set grid
|
||||
|
||||
set style line 1 lc rgb "#0060ad" lt 1 lw 2 pt 7 ps 1
|
||||
|
||||
plot "profile/samples/lexer/big_xml.txt" \
|
||||
using 0:($1 / 1024 ** 2) \
|
||||
with linespoints ls 1 \
|
||||
title "Memory"
|
||||
|
||||
# vim: set ft=gnuplot:
|
|
@ -0,0 +1,41 @@
|
|||
require_relative '../lib/oga'
|
||||
|
||||
##
|
||||
# Returns memory usage in bytes. This relies on the /proc filesystem, it won't
|
||||
# work without it.
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
def memory_usage
|
||||
return File.read('/proc/self/status').match(/VmRSS:\s+(\d+)/)[1].to_i * 1024
|
||||
end
|
||||
|
||||
##
|
||||
# Reads a big XML file and returns it as a String.
|
||||
#
|
||||
# @return [String]
|
||||
#
|
||||
def read_big_xml
|
||||
return File.read(File.expand_path('../../benchmark/fixtures/big.xml', __FILE__))
|
||||
end
|
||||
|
||||
##
|
||||
# Writes memory samples to a file until the thread is killed.
|
||||
#
|
||||
# @param [String] name The name of the samples file.
|
||||
# @param [Fixnum] interval The sample interval. The default is 200 ms.
|
||||
# @return [Thread]
|
||||
#
|
||||
def profile_memory(name, interval = 0.2)
|
||||
return Thread.new do
|
||||
path = File.expand_path("../samples/#{name}.txt", __FILE__)
|
||||
handle = File.open(path, 'w')
|
||||
handle.sync = true
|
||||
|
||||
loop do
|
||||
handle.write("#{memory_usage}\n")
|
||||
|
||||
sleep(interval)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue