tag:www.rhnh.net,2008:/benchmark
Benchmark - Xavier Shay's Blog
2009-08-10T20:12:55Z
Enki
Xavier Shay
notreal@rhnh.net
tag:www.rhnh.net,2008:Post/800
2009-08-10T19:48:00Z
2009-08-10T20:12:55Z
Benchmarks for creating a new array
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span class="s"><span class="dl">'</span><span class="k">benchmark</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt>n = <span class="i">1000</span><tt>
</tt>m = <span class="i">50000</span><tt>
</tt>blank = [<span class="i">0</span>] * m<tt>
</tt><span class="co">Benchmark</span>.bm(<span class="i">7</span>) <span class="r">do</span> |x|<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k">.new with block:</span><span class="dl">"</span></span>) { (<span class="i">0</span>..n).collect { <span class="co">Array</span>.new(m) { <span class="i">0</span> } }}<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k"> .new no block:</span><span class="dl">"</span></span>) { (<span class="i">0</span>..n).collect { <span class="co">Array</span>.new(m, <span class="i">0</span>) }}<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k"> [0] * x:</span><span class="dl">"</span></span>) { (<span class="i">0</span>..n).collect { [<span class="i">0</span>] * m }}<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k"> #dup:</span><span class="dl">"</span></span>) { (<span class="i">0</span>..n).collect { blank.dup }}<tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">$ ruby19 benchmark.rb <tt>
</tt> user system total real<tt>
</tt>.new with block: 10.180000 0.210000 10.390000 ( 10.459538)<tt>
</tt> .new no block: 3.690000 0.210000 3.900000 ( 3.915348)<tt>
</tt> [0] * x: 4.280000 0.210000 4.490000 ( 4.505334)<tt>
</tt> #dup: 0.000000 0.000000 0.000000 ( 0.000491)<tt>
</tt></pre></td>
</tr></table>
<p>Know your constructors! What is <code>#dup</code> doing? I think it’s cheating.</p>
tag:www.rhnh.net,2008:Post/787
2008-11-03T08:54:00Z
2008-11-03T08:54:09Z
Comparing lambdas in ruby
<p><code>to_ruby</code> is a really convenient way to compare the equality of two lambdas. It’s a bit slow though. If we get our hands dirty (only a little!) with ParseTree, we can get a result 2 orders of magnitude quicker. I’d be interested to see if these benchmarks differ significantly on other versions of ruby.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">~ $ ruby -v<tt>
</tt>ruby 1.8.6 (2007-09-23 patchlevel 110) [i686-darwin8.11.1]<tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt>25<tt>
</tt>26<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span class="s"><span class="dl">'</span><span class="k">benchmark</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">parse_tree</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">ruby2ruby</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt><span class="r">def</span> <span class="fu">gen_lambda</span><tt>
</tt> lambda {|x| x + <span class="i">1</span> }<tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="co">Parser</span> = <span class="co">ParseTree</span>.new(<span class="pc">false</span>)<tt>
</tt><tt>
</tt><span class="c"># This only requires parse tree, not ruby2ruby</span><tt>
</tt><span class="r">def</span> <span class="fu">proc_identity</span>(block)<tt>
</tt> klass = <span class="co">Class</span>.new<tt>
</tt> name = <span class="s"><span class="dl">"</span><span class="k">myproc</span><span class="dl">"</span></span><tt>
</tt> klass.send(<span class="sy">:define_method</span>, name, &block)<tt>
</tt><tt>
</tt> <span class="c"># .last ignores the method name and definition - they're irrelevant</span><tt>
</tt> <span class="co">Parser</span>.parse_tree_for_method(klass, name).last <tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>n = <span class="i">1000</span><tt>
</tt><span class="co">Benchmark</span>.bmbm <span class="r">do</span> |x|<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k">#to_ruby</span><span class="dl">"</span></span>) { n.times { gen_lambda.to_ruby == gen_lambda.to_ruby }}<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k">#to_sexp</span><span class="dl">"</span></span>) { n.times { gen_lambda.to_sexp == gen_lambda.to_sexp }}<tt>
</tt> x.report(<span class="s"><span class="dl">"</span><span class="k">manual</span><span class="dl">"</span></span>) { n.times { proc_identity(gen_lambda) == proc_identity(gen_lambda) }}<tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"> user system total real<tt>
</tt>#to_ruby 4.460000 0.220000 4.680000 ( 4.695327)<tt>
</tt>#to_sexp 0.920000 0.190000 1.110000 ( 1.110214)<tt>
</tt>manual 0.030000 0.000000 0.030000 ( 0.032768)<tt>
</tt></pre></td>
</tr></table>
<p>In case you were wondering, I was playing around with this while implementing <a href="http://github.com/xaviershay/dm-more/tree/master/dm-sweatshop">unique data generation for dm-sweatshop</a></p>