From 53c45c621b1087443b613304a7008b91b91085aa Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 29 Apr 2014 13:38:56 +0200 Subject: [PATCH] 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. --- .gitignore | 3 +++ profile/lexer/big_xml.rb | 8 ++++++ profile/plot/lexer/big_xml.gnuplot | 20 +++++++++++++++ profile/profile_helper.rb | 41 ++++++++++++++++++++++++++++++ profile/samples/.gitkeep | 0 profile/samples/lexer/.gitkeep | 0 6 files changed, 72 insertions(+) create mode 100644 profile/lexer/big_xml.rb create mode 100755 profile/plot/lexer/big_xml.gnuplot create mode 100644 profile/profile_helper.rb create mode 100644 profile/samples/.gitkeep create mode 100644 profile/samples/lexer/.gitkeep diff --git a/.gitignore b/.gitignore index 3359fde..92805d5 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/profile/lexer/big_xml.rb b/profile/lexer/big_xml.rb new file mode 100644 index 0000000..20db5bf --- /dev/null +++ b/profile/lexer/big_xml.rb @@ -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| } diff --git a/profile/plot/lexer/big_xml.gnuplot b/profile/plot/lexer/big_xml.gnuplot new file mode 100755 index 0000000..8dc2129 --- /dev/null +++ b/profile/plot/lexer/big_xml.gnuplot @@ -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: diff --git a/profile/profile_helper.rb b/profile/profile_helper.rb new file mode 100644 index 0000000..d021579 --- /dev/null +++ b/profile/profile_helper.rb @@ -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 diff --git a/profile/samples/.gitkeep b/profile/samples/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/profile/samples/lexer/.gitkeep b/profile/samples/lexer/.gitkeep new file mode 100644 index 0000000..e69de29