<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SmartLogic Solutions Blog &#187; Benchmarking</title>
	<atom:link href="http://blog.smartlogicsolutions.com/category/testing/benchmarking/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smartlogicsolutions.com</link>
	<description>News and updates from the people at SmartLogic Solutions</description>
	<lastBuildDate>Tue, 30 Nov 2010 21:39:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Slow Actions in Rails Projects</title>
		<link>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 20:08:34 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[Benchmarking]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=565</guid>
		<description><![CDATA[MySQL&#8217;s slow query log is a very handy tool to detect which SQL queries are running slowly in a production app. So what about rails applications? Often, test data only contains a small amount of data. Over time more users use the site and generate more data. A page that usually renders in 100ms could [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html">MySQL&#8217;s slow query log</a> is a very handy tool to detect which SQL queries are running slowly in a production app.</p>
<p>So what about rails applications? Often, test data only contains a small amount of data. Over time more users use the site and generate more data. A page that usually renders in 100ms could be taking 3-5 seconds, or more!</p>
<p>I present, <a href="http://github.com/ngauthier/slow-actions/tree/master">SlowActions</a>. The goal was to analyze a standard log file to detect actions that render slowly. It had to be easy to use and also not require modification of rails&#8217; logging mechanism. Observe:</p>
<pre>  $> slow-actions --actions development.log
             Cost    Average Max
  - UsersController : game_history (22 entries, 0% Error)
    Total:   11275.447 3642.437 12728.0
    Render:  7.20300 2.32700 17.2450
    DB:      10.5020 3.39200 10.0000

  - QuestionsController : refresh_index_table (89 entries, 0% Error)
    Total:   908.494 202.348 307.000
    Render:  0.00000 0.00000 0.00000
    DB:      32.5880 7.25800 10.0000
</pre>
<p>More info after the break &#8230;.<br />
<span id="more-565"></span></p>
<p>So, what are we looking at? These are the top two (because I cut off the rest) results for looking at all the log entries times sorted by their Cost. The first line is the Controller followed by the Action. In parenthesis is the number of entries in the log file and the percent of those entries that had an error.</p>
<p>The second line is the total time from request to the data being sent to the user. There is a column for Cost, Avg, and Max. Max is the maximum time this action ever took. Avg is the average amount of time the action took (not counting errors). Cost = Avg * Math.Log(# entries).</p>
<p>The Cost can be thought of as that action&#8217;s share of the slowness of the site. An action that is only run once a month and takes 5 seconds is not as bad as an action run 200 times per day that takes 1 second. The Log helps smooth things out a bit.</p>
<p>There are a bunch of filters that you can put on the command:</p>
<pre>$> slow-actions (--actions | --controllers | --sessions) log_file [log_file ...]
    You may also specify:
      --min-cost=FLOAT
      --min-avg=FLOAT
      --min-max=FLOAT
      --start-date=YYYY-MM-DD
      --end-date=YYYY-MM-DD
</pre>
<p>You can choose to output the actions and/or controllers (in a tree format) and/or the session ids (to see which users have it the worst, this is great to find out what is causing a slow action). You can also specify multiple log files, in case you rotate your logs.</p>
<p>You can choose a cutoff cost/avg/max, which means that you could make nice short little emails to yourself every night from your app.</p>
<p>You can also specify a date range, because after you fix a bug, you want to see what kind of effect it had.</p>
<p>I took care to put in some basic RDoc to help people use slow-actions in their own tests or tasks. For example, you could run this in irb:</p>
<pre>require 'rubygems'
require 'slow_actions'
@sa = SlowActions.new
@sa.parse_file('/path/to/my/log')
puts @sa.print_actions</pre>
<p>Have I convinced you? Then get <a href="http://github.com/ngauthier/slow-actions/tree/master">SlowActions</a> off GitHub and download it and run it on your app, you&#8217;ll be surprised!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/05/04/find-the-unique-sessions-for-a-rails-application/" rel="bookmark" class="crp_title">Find the Unique Sessions for a Rails Application</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/problems-with-restful_authentication-plugin-and-internet-explorer-cookies/" rel="bookmark" class="crp_title">Problems with restful_authentication Plugin and Internet Explorer Cookies</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/12/watch-multiple-logs-in-a-single-terminal/" rel="bookmark" class="crp_title">Watch Multiple Logs in a Single Terminal</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/09/07/nicks-highlights-from-ruby-hoedown/" rel="bookmark" class="crp_title">Nick&#8217;s Highlights from Ruby Hoedown</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/06/deploying-rails-apps-with-capistrano-without-root-or-sudo-privileges/" rel="bookmark" class="crp_title">Deploying Rails Apps with Capistrano without root or sudo Privileges</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmark Ruby Code with R, rsruby and better-benchmark</title>
		<link>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 16:53:38 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[Benchmarking]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[mac osx]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[rsruby]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=275</guid>
		<description><![CDATA[I&#8217;ve found myself on a benchmarking kick these last couple of weeks. Sometime last week, I dug up the better-benchmark library written by Pistos. Pistos&#8217; library is basically just a wrapper for the rsruby gem, which is more or less an interface to R (similar to what rmagick is to ImageMagick). Combining these tools together, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found myself on a benchmarking kick these last couple of weeks.  Sometime last week, I dug up the <a href="http://github.com/Pistos/better-benchmark/tree/master">better-benchmark</a> library written by <a href="http://github.com/Pistos">Pistos</a>.  Pistos&#8217; library is basically just a wrapper for the <a href="http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/">rsruby gem</a>, which is more or less an interface to <a href="http://www.r-project.org/">R</a> (similar to what <a href="http://rmagick.rubyforge.org/">rmagick</a> is to <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a>).</p>
<p>Combining these tools together, we can do some pretty nifty code performance analysis in very few lines of code, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'better-benchmark'</span>
&nbsp;
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  save_the_world<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  save_the_world_and_save_the_girl<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result</pre></div></div>

<p>I have <a href="http://github.com/jtrupiano/better-benchmark/tree/master">forked better-benchmark</a> and wrapped the library up into a <a href="http://www.rubygems.org/">RubyGem</a>.  </p>
<p><span id="more-275"></span></p>
<p>Currently, the gem is available from github:</p>
<pre>
$> sudo gem install jtrupiano-better-benchmark
</pre>
<p>Based on preliminary discussions with Pistos, he intends to merge my changes back into his branch.  I&#8217;ll update this post with the relevant details when that has been completed.</p>
<p>So, let&#8217;s get started by preparing your box for better-benchmark!</p>
<h2>Installing R</h2>
<h3>On Mac OSX</h3>
<p>This one&#8217;s simple.  AT&#038;T Research provides us with a <a href="http://r.research.att.com/">DMG</a>.</p>
<h3>On Ubuntu 8.0.4</h3>
<p>I first built this just fine on a Mac.  But, I decided that I wanted a dedicated VM where I could run some fairly intense benchmarks.  You&#8217;ll need to ensure you have the following apt packages installed:</p>
<p>* build-essential<br />
* g77 (fortran compiler)<br />
* x11-common</p>
<p>There may be a few others that are required, but I started on a pre-built box more or less ready to host rails apps, and so there may be a few other necessities I missed.  The following steps will install R from source on Ubuntu (I was unable to get the necessary R headers installed using apt-get or apititude), and prepare you for installing the rsruby gem.</p>
<pre>
$> sudo apt-get install build-essential g77 x11-common
$> cd /opt
$> wget http://lib.stat.cmu.edu/R/CRAN/src/base/R-2/R-2.7.2.tar.gz
$> tar xzf R-2.7.2.tar.gz
$> cd R-2.7.2
# --enable-R-shlib is important...it signals the installer to build and make available libR.so
$> ./configure --enable-R-shlib
$> make
$> sudo make install
</pre>
<h2>Installing rsruby</h2>
<p>Assuming you installed R fine, rsruby should be easily installed using gem.  If you have trouble, see the <a href="http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/">installation instructions</a> on the project&#8217;s README.</p>
<p>Note that you&#8217;ll need to set the R_HOME environment variable prior to installing the gem.  On Mac, R_HOME=/Library/Frameworks/R.framework/Resources.  On Ubuntu (when installed from source), R_HOME=/usr/local/lib/R.  I find it helpful to just drop this into /etc/environment (on Ubuntu) so that this variable is set upon login.</p>
<pre>
$> export R_HOME=/path/to/R/for/your/OS
$> sudo gem install rsruby -- --with-R-dir=$R_HOME
</pre>
<h2>Installing better-benchmark</h2>
<p>Currently, you can get this directly off of my fork on github.</p>
<pre>
$> gem sources -a http://gems.github.com/
$> sudo gem install jtrupiano-better-benchmark
</pre>
<h2>Great, I have it, now what do I do with it??</h2>
<p>So now we&#8217;re ready to benchmark something.  The most important thing to understand when benchmarking is that you need to clearly identify what is part of the benchmark, and what is not.  Let&#8217;s take a look at a real-world example.  We&#8217;ll go through the following steps:</p>
<ol>
<li><strong>Hypothesize: </strong>define exactly what you&#8217;re looking to test, and take special care to describe what you are NOT testing.</li>
<li><strong>Plan: </strong>write out step by step how you will accomplish your benchmark</li>
<li><strong>Refine: </strong>identify which steps belong in the benchmark, and which are really setup/teardown aspects of the benchmark, and thus shouldn&#8217;t be included in the test.</li>
<li><strong>Test: </strong>run the benchmarks</li>
<li><strong>Rinse/Repeat: </strong>(as necessary) tweak your test parameters, tweak the tests, re-test </li>
</ol>
<h2>Real world example</h2>
<p>I was building a set of services that needed to download tens to hundreds of thousands of feeds regularly and perform some post-processing.  I pulled in the <a href="http://feed-normalizer.rubyforge.org/">feed-normalizer</a> gem.  My implementation plan called for me to write separate services, one for &#8220;pulling down&#8221; the feed, and one for &#8220;processing&#8221; the feed.  </p>
<p>My first approach entailed storing the feeds on the hard-drive as YAML (using the to_yaml function).  After running into <a href="http://blog.smartlogicsolutions.com/2008/09/04/ruby-patch-to-fix-broken-yamldump-for-multi-line-strings-stringto_yaml/">some obscure problems with YAML and multi-line strings</a>, I started to explore alternative persistence formats.  One that caught my attention was using the Marshall standard library to store the content as bytecode.  This brings me to my hypothesis:</p>
<p><strong>1) Hypothesis: </strong>Converting FeedNormalizer::Feed objects to bytecode using the Marshal library is faster than converting those same obejcts to YAML using the YAML library.</p>
<p>I also like to list out my goals at this stage:</p>
<ol>
<li>We only want to test the #dump conversion (object &#8211;> string) and the #read conversion (string &#8211;> object).  We do not want to test the write to disk and the read from disk portions.</li>
<li>We specifically want to test FeedNormalizer::Feed objects, since that&#8217;s what we&#8217;re using in our code.</li>
<li>Let&#8217;s benchmark YAML / Marshal #dump and #read methods specifically on FeedNormalizer::Feed objects</li>
</ol>
<p><strong>2) Plan: </strong> </p>
<ol>
<li>We have already grabbed roughly 100 feed downloads, and they are sitting as raw xml in test/raw_rss.</li>
<li>We&#8217;ll read them in, then benchmark YAML.dump vs. Marshal.dump</li>
<li>Then we&#8217;ll independently benchmark YAML.read vs. Marshal.read</li>
</ol>
<p><strong>3) Refine: </strong><br />
Here&#8217;s where we need to ensure that unnecessary processing doesn&#8217;t make its way into our benchmarks.  For instance, in order to benchmark Marshal#dump against YAML#dump, we&#8217;ll need to load up all of the FeedNormalizer::Feed objects (by reading them from disk and instantiating them) prior to starting the benchmark.</p>
<p><strong>4) Test: </strong><br />
It&#8217;s a ruby script, so go ahead and run it.  The set of options provided by better-benchmark are easily discernible from the <a href="http://github.com/jtrupiano/better-benchmark/tree/master/lib/better-benchmark/better-benchmark.rb">source file</a>.</p>
<p><strong>5) Rinse/Repeat: </strong><br />
Same story as always.</p>
<h2>Real Script Example</h2>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#008000; font-style:italic;"># Author: John Trupiano</span>
<span style="color:#008000; font-style:italic;"># 2008-09-28</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># In order to run this benchmark, you need to have the better-benchmark library installed (http://github.com/Pistos/better-benchmark/tree/master)</span>
<span style="color:#008000; font-style:italic;"># better-benchmark depends on the rsruby gem (http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/)</span>
<span style="color:#008000; font-style:italic;"># rsruby depends on an installation of the computing package R (http://mirrors.ibiblio.org/pub/mirrors/CRAN/)</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># For details on setting up R, rsruby, and better-benchmark, see this blog post: http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># This is intended to be run from RAILS_ROOT, e.g.</span>
<span style="color:#008000; font-style:italic;"># /path/to/rails/root $&gt; ruby test/benchmark/yaml_bytecode_test.rb</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'openssl'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'yaml'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'feed-normalizer'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'lib/rss_parser'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'better-benchmark'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># GOALS </span>
<span style="color:#008000; font-style:italic;"># 1) We only want to test the #dump conversion (object --&gt; string) and the #read conversion (string --&gt; object).  We do not want to test the write to disk and the read from disk portions.</span>
<span style="color:#008000; font-style:italic;"># 2) We specifically want to test FeedNormalizer::Feed objects, since that's what we're using in our code.</span>
<span style="color:#008000; font-style:italic;"># 3) Let's benchmark YAML / Marshal #dump and #read methods specifically on FeedNormalizer objects</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># PLAN</span>
<span style="color:#008000; font-style:italic;"># 1) We've grabbed roughly 100 feed downloads sitting in test/raw_rss.</span>
<span style="color:#008000; font-style:italic;"># 2) We'll read them in, then benchmark YAML.dump vs. Marshal.dump</span>
<span style="color:#008000; font-style:italic;"># 3) Then we'll independently benchmark YAML.read vs. Marshal.read</span>
&nbsp;
fn_feeds = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
root_dir = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;test&quot;</span>, <span style="color:#996600;">&quot;raw_rss&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
feed_ids = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span>..<span style="color:#006666;">62</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_a</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">64</span>..<span style="color:#006666;">108</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_a</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># build a global hash fn_feeds that contains the FeedNormalizer::Feed entries</span>
feed_ids.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id<span style="color:#006600; font-weight:bold;">|</span>
  infile = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>root_dir, feed_id.<span style="color:#9900CC;">to_s</span>, feed_id.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'_dump.rss'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  fn_feeds<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = RssParser.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>infile, <span style="color:#ff3333; font-weight:bold;">:file</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#### BENCHMARK 1 ####</span>
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">25</span>,
  <span style="color:#ff3333; font-weight:bold;">:verbose</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result
&nbsp;
&nbsp;
<span style="color:#008000; font-style:italic;"># now, let's create separate collections storing the dumps</span>
yaml_dumps = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
marshal_dumps = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
  yaml_dumps<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  marshal_dumps<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#### BENCHMARK 2 ####</span>
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">25</span>,
  <span style="color:#ff3333; font-weight:bold;">:verbose</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  yaml_dumps.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, yaml<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>yaml<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  marshal_dumps.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, marshal<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>marshal<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result</pre></div></div>

<p>And for good measure, let&#8217;s take a look at the results.</p>
<pre>
john-trupianos-macbook-pro:trunk john$ ruby test/benchmark/yaml_bytecode_test.rb
.........................
Set 1 mean: 2.095 s
Set 1 std dev: 0.071
Set 2 mean: 0.123 s
Set 2 std dev: 0.019
p.value: 1.58214572048972e-14
W: 625.0
The difference (-94.1%) IS statistically significant.
.........................
Set 1 mean: 0.191 s
Set 1 std dev: 0.015
Set 2 mean: 0.022 s
Set 2 std dev: 0.012
p.value: 1.58214572048972e-14
W: 625.0
</pre>
<p>As R plainly tells us, the difference is statistically significant (those who remember their p-values from stats class raise your hands) for both benchmarks (note that I did run two separate benchmarks in this example, one for dumping and one for reading).  That said, considering I don&#8217;t have a need for this data to be human readable on my filesystem, I can safely conclude that using the Marshal library in lieu of the YAML library will give me a performance boost on both the read/dump methods.  Now, whether or not this boost is negligible in the scope of the greater system, well that&#8217;s a question for a separate benchmark.</p>
<p>(What I mean by this last part is that this #dump/#read portion of my whole system may be tiny.  If it only represents 0.5% of the processing time, then the improvement my example shows may be more or less negligible in the context of the whole system.  These are the types of questions you need to ask yourself when benchmarking.)</p>
<p>Primary take-home point:  <strong>know what you&#8217;re benchmarking, and benchmark what you don&#8217;t know</strong>.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/09/04/ruby-patch-to-fix-broken-yamldump-for-multi-line-strings-stringto_yaml/" rel="bookmark" class="crp_title">Ruby: Patch to fix broken YAML.dump for multi-line strings (String#to_yaml)</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/" rel="bookmark" class="crp_title">Setting Up Ubuntu 9.10 for Ruby On Rails Development</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/07/i-cant-upgrade-rubygems-from-111-to-120-on-ubuntu/" rel="bookmark" class="crp_title">I can&#8217;t upgrade RubyGems from 1.1.1 to 1.2.0 on Ubuntu</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/01/14/aptinstaller-032-released/" rel="bookmark" class="crp_title">Aptinstaller 0.3.2 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/06/04/mount-options-to-improve-ext4-file-system-performance/" rel="bookmark" class="crp_title">Mount options to improve ext4 file system performance</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

