<?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>Zen and the Art of Programming &#187; Ruby</title>
	<atom:link href="http://programmingzen.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingzen.com</link>
	<description>By Antonio Cangiano, Software Engineer &#38; Technical Evangelist at IBM</description>
	<lastBuildDate>Wed, 21 Jul 2010 22:12:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>The Great Ruby Shootout (July 2010)</title>
		<link>http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/</link>
		<comments>http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 18:12:31 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Benchmark Suite]]></category>

		<guid isPermaLink="false">http://programmingzen.com/?p=1233</guid>
		<description><![CDATA[The Great Ruby Shootout measures the performance of several Ruby implementations by testing them against a series of synthetic benchmarks. Recently I ran Mac and Windows shootouts as well, which tested a handful of implementations. However this article reports on the results of extensive benchmark testing of eight different Ruby implementations on Linux. The setup [...]]]></description>
			<content:encoded><![CDATA[<p>The Great Ruby Shootout measures the performance of several Ruby implementations by testing them against a series of synthetic benchmarks. Recently I ran <a href="http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/">Mac</a> and <a href="http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/">Windows</a> shootouts as well, which tested a handful of implementations. However this article reports on the results of extensive benchmark testing of eight different Ruby implementations on Linux.</p>
<p><strong>The setup</strong></p>
<p>For this shootout I included a subset of the <a href="http://github.com/acangiano/ruby-benchmark-suite">Ruby Benchmark Suite</a>. I opted to primarily exclude tests that were executed in fractions of a second in most VMs, focusing instead of more substantial benchmarks (several of which came from the <a href="http://shootout.alioth.debian.org/">Computer Language Benchmarks Game</a>). The best times and least memory allocations out of five runs are reported here for each benchmark.</p>
<p>All tests were run on Ubuntu 10.4 LTS x86_64, on an Intel Core 2 Quad Q6600 2.40 GHz, 8 GB DDR2 RAM, with two 500 GB 7200 rpm disks.</p>
<p><strong>8 implementations</strong></p>
<p>The implementations tested were:</p>
<ul>
<li>Ruby 1.8.7 p299</li>
<li>Ruby 1.9.1 p378</li>
<li>Ruby 1.9.2 RC2</li>
<li>IronRuby 1.0 (Mono 2.4.4)</li>
<li>JRuby 1.5.1 (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20)</li>
<li>MagLev (rev 23832)</li>
<li>Ruby Enterprise Edition 2010.02</li>
<li>Rubinius 1.0.1</li>
</ul>
<p>JRuby was run with the &#8211;fast and &#8211;server optimization flags.</p>
<p><strong>Disclaimer</strong></p>
<p>Synthetic benchmarks cannot predict how fast your programs will be when dealing with a particular implementation. They provide an (entertaining) educated guess, but you shouldn’t draw overly definitive conclusions from them. The values reported here should be assumed to be characteristic of server-side &mdash; and long running &mdash; processes; they should be taken with a grain of salt.</p>
<p><strong>Time Results</strong></p>
<p>Please find below the execution times for the selected tests. Timeouts indicate that the execution of a single iteration for a given test took more than 300 seconds and had to be interrupted. Bold, green values indicate the best performer out of each test.</p>
<p><em>Warning: The bm_primes.rb benchmark was originally written to aid the development of the Prime class. As such in 1.9.2 it was rewritten in C, which makes it a poor representation of implementation performance. This benchmark will removed in the future.</em> </p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-time-table1.png" alt="Time Table on Linux" /></p>
<p>If you are not interested in the individual test results, the information presented in the table above is summarized directly below:</p>
<pre class="highlight">
  Ruby 1.9.2         JRuby
Min.   : 0.013   Min.   : 0.382
1st Qu.: 3.258   1st Qu.: 3.051
Median : 4.543   Median : 4.997
Mean   : 9.262   Mean   : 9.180
3rd Qu.: 8.573   3rd Qu.: 8.969
Max.   :45.009   Max.   :48.850

    MagLev         Ruby 1.9.1
Min.   : 0.351   Min.   : 0.015
1st Qu.: 2.140   1st Qu.: 3.387
Median : 6.069   Median : 6.205
Mean   : 9.100   Mean   :10.860
3rd Qu.: 9.266   3rd Qu.:11.559
Max.   :51.221   Max.   :46.849

 Ruby 1.8.7         IronRuby
Min.   : 0.708   Min.   :  3.601
1st Qu.: 5.102   1st Qu.: 10.505
Median : 8.380   Median : 12.912
Mean   :18.785   Mean   : 26.539
3rd Qu.:24.793   3rd Qu.: 36.115
Max.   :75.653   Max.   :135.204

   Rubinius           REE
Min.   : 0.484   Min.   : 0.584
1st Qu.: 3.087   1st Qu.: 4.343
Median : 9.636   Median : 6.660
Mean   :13.232   Mean   :15.036
3rd Qu.:17.674   3rd Qu.:21.336
Max.   :73.050   Max.   :61.960
</pre>
<p>For the sake of convenience, I also produced a box plot from the successful data points:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-time-plot.png" alt="Box plot of times"/></p>
<p>There are a few considerations based on these results that I feel are worth mentioning:</p>
<ul>
<li>As you can see Ruby 1.9, JRuby and MagLev converge towards a similar performance level according to these tests.</li>
<li>Ruby 1.9.2 manages to squeeze in a bit of extra speed when compared to Ruby 1.9.1 (which is a welcome improvement).</li>
<li>Ruby 1.9 seems to be either much faster than Ruby 1.8 or roughly as fast, depending on the test. This appears to be in line with what I&#8217;ve seen in real world programs. There are programs that will only receive a 10-20% boost from 1.9, while others improve drastically. The results really depends on what a program spends its time doing.</li>
<li>Performance wise, Rubinius is really starting to be a much more serious contender.</li>
<li>Ruby Enterprise Edition is slightly faster than Ruby 1.8.7, to the extent where this is clearly visible in almost all of the tests.</li>
<li>IronRuby running on Mono was the worse of the lot.</li>
</ul>
<p><strong>Memory Results</strong></p>
<p>The following table shows the approximate memory consumption for each implementation when running each benchmark:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-memory-table.png" alt="Memory allocation on Linux" /></p>
<p>Summarized:</p>
<pre class="highlight">
  Ruby 1.9.2        Ruby 1.9.1
Min.   :  4.320   Min.   :  4.580
1st Qu.:  4.378   1st Qu.:  4.695
Median :  6.285   Median :  6.920
Mean   : 20.795   Mean   : 15.669
3rd Qu.: 10.162   3rd Qu.: 11.383
Max.   :171.500   Max.   :100.570

   Ruby 1.8            REE
Min.   :  3.040   Min.   :  8.220
1st Qu.:  4.290   1st Qu.:  9.682
Median :  7.745   Median : 15.565
Mean   : 20.698   Mean   : 27.014
3rd Qu.: 11.273   3rd Qu.: 38.620
Max.   :103.520   Max.   :125.910

  Rubinius           MagLev
Min.   : 37.63   Min.   : 81.74
1st Qu.: 39.78   1st Qu.: 82.52
Median : 45.48   Median : 83.53
Mean   : 65.70   Mean   : 96.29
3rd Qu.: 58.22   3rd Qu.: 98.10
Max.   :215.33   Max.   :175.85   

    JRuby
Min.   : 49.04
1st Qu.: 71.23
Median :176.72
Mean   :169.41
3rd Qu.:209.04
Max.   :404.06
</pre>
<p>And finally, in graph form:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-memory-plot1.png" alt="Memory Box Plot" /></p>
<p>A few considerations on memory:</p>
<ul>
<li>Memory readings for IronRuby were not available, so they were not included.</li>
<li>Ruby 1.9.2 uses the least amount of memory (as one might expect).</li>
<li>JRuby was by far the most memory intensive of the group.</li>
<li>Ruby Enterprise Edition used less memory than 1.8.7 in a few tests, but overall was more memory hungry than 1.8.7. This is really odd and entirely unexpected.</li>
</ul>
<p><strong>Linux Vs. Windows</strong></p>
<p>This shootout and the Windows one were both performed on the same machine, thus we can compare how the same implementation perform under different operating systems. The only adjustment that’s required is the timeout. Every result longer than 60 seconds from this shootout needs to be considered a timeout, because the previous shootout did so as well.</p>
<p>It is commonly believed that Ruby performs much better on Linux than on Windows (with the exception of IronRuby). Let&#8217;s find out if these test results confirm that notion.</p>
<p>Ruby 1.8.7:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-187-table.png" alt="Ruby 1.8.7 on Linux and Windows" /></p>
<p>Ruby 1.9.2:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-192-table.png" alt="Ruby 1.9.2 on Linux and Windows" /></p>
<p>JRuby:</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-jruby-table.png" alt="JRuby on Linux and Windows" /></p>
<p>Finally, in chart form (yellow entries are on Windows as indicated by the labels containing W):</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-plot.png" alt="Ruby on Linux Vs. Windows" /></p>
<p>To use a beloved MythBusters expression, this myth is confirmed.</p>
<p><strong>Note</strong>: As requested by a few commenters, here is a comparison of IronRuby as well (.NET 4.0 Vs. Mono 2.4.4):</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-ir-table.png" alt="Ruby 1.8.7 on Linux and Windows" /></p>
<p><strong>Conclusion</strong></p>
<p>In conclusion, let me just state that it’s nice to see several implementations getting faster. Ruby 1.9.2, JRuby, MagLev and Rubinius are all becoming serious competitors and working their respective ways closer to a similar performance level. If you think these benchmark shootouts are becoming boring, then the results are becoming more stable and predictable. I suspect that as time goes on, performance will not be the real distinguishing factor when choosing a Ruby implementation, other features will be.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/feed/</wfw:commentRss>
		<slash:comments>74</slash:comments>
		</item>
		<item>
		<title>Thoughts on Clojure</title>
		<link>http://programmingzen.com/2010/07/09/thoughts-on-clojure/</link>
		<comments>http://programmingzen.com/2010/07/09/thoughts-on-clojure/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 18:00:32 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://programmingzen.com/?p=1225</guid>
		<description><![CDATA[Lisp has had a tremendous impact on the world of programming. Even though Common Lisp and Scheme &#8212; the two main Lisp dialects &#8212; may not be considered mainstream today, several popular languages have been influenced by one or both of them. It isn&#8217;t stretching things too much to say that both Ruby and Python [...]]]></description>
			<content:encoded><![CDATA[<p>Lisp has had a tremendous impact on the world of programming. Even though Common Lisp and Scheme &mdash; the two main Lisp dialects &mdash; may not be considered mainstream today, several popular languages have been influenced by one or both of them.</p>
<p>It isn&#8217;t stretching things too much to say that both Ruby and Python can be seen as slower, easier (for beginners), object-oriented, infix Lisp dialects.</p>
<blockquote><p>Some may say Ruby is a bad rip-off of Lisp or Smalltalk, and I admit that. But it is nicer to ordinary people. &mdash; Yukihiro &#8220;Matz&#8221; Matsumoto</p></blockquote>
<p>Ruby and Python aren&#8217;t intimidating and remain very approachable for absolute beginners. Furthermore, their approachability is not confined to the language design itself, but transcends into the community and ecosystem that surrounds them.</p>
<p>I&#8217;m not here to discuss how languages like Ruby and Python managed to become more popular than major Lisp dialects nowadays. I&#8217;d rather focus on how these gentler introductions to functional programming are acting as gateway drugs to Lisp for many developers.</p>
<p>A community that values metaprogramming and is obsessed with the construction of DSLs (Domain Specific Languages) like the Ruby&#8217;s is, will no doubt find in Lisp a valuable ally. Plus, if you know Ruby inside and out, you should find Lisp to be easy enough to learn.</p>
<p>To attract Ruby developers though, Lisp has to offer something more than just a set of powerful features. You could say that Rails is enough of a reason to learn and use Ruby. But what is Lisp able to solve all that better than Ruby? I&#8217;ll answer that question by focusing on a specific dialect of Lisp, that I and continually more Ruby developers are getting into: <a href="http://clojure.org">Clojure</a>.</p>
<p>It wouldn&#8217;t be fair to characterize the Lisp community as stagnant, but Clojure is definitely a welcomed dose of new blood. Clojure is a JVM-based modern Lisp designed for concurrency, which elegantly includes a set of carefully chosen features that are not easily found in mainstream languages.</p>
<p>In my opinion, Clojure has three main advantages over Ruby:</p>
<ul>
<li>It&#8217;s much faster than Ruby, which makes it a better choice for intensive processing. (<a href="http://www.infoq.com/articles/flightcaster-clojure-rails">FlightCaster</a> for example, uses both Rails and Clojure. Rails for the &#8220;front-end&#8221; and Clojure for the heavy lifting/forecasting.)</li>
<li>It greatly simplifies concurrent programming, making the language more future-proof as hardware manufacturers continue to produce processors with more CPU cores.</li>
<li>Clojure emphasizes functional programming and tries to minimize side effects.</li>
</ul>
<p>Clojure&#8217;s interoperability with Java resolves the issue of only having a few available libraries, which often affects new languages. It also helps in getting people to use the language within the enterprise world where Java still dominates.</p>
<p>Of all the &#8220;new&#8221; languages out there, I find Clojure to be the most fun, interesting and pragmatic: it&#8217;s something worth getting excited about. I don&#8217;t really care if it turns out to be the next Ruby or not, it&#8217;s a language that&#8217;s worth knowing and using. (If you haven&#8217;t tried it yet, a decent, short introductory book is the recently published <a href="http://programmingzen.com/recommends/?1430272317">Practical Clojure</a>.)</p>
<p>Clojure&#8217;s popularity may even bring more attention to Lisp in general (for example, most <a href="http://programmingzen.com/recommends/?0262011530">must-read</a> literature uses Scheme or Common Lisp). Perhaps then, it may indirectly help introduce more traditional Lisp dialects to a new generation of programmers.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2010/07/09/thoughts-on-clojure/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The Great Ruby Shootout (Windows Edition)</title>
		<link>http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/</link>
		<comments>http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 19:00:28 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Benchmark Suite]]></category>

		<guid isPermaLink="false">http://programmingzen.com/?p=1220</guid>
		<description><![CDATA[This post contains the results of a Ruby shootout on Windows that I recently conducted. You can find the Mac edition, published last month, here. I was planning to have this one ready much sooner, but a couple of serious events in personal life prevented that from happening. Be sure to grab my feed or [...]]]></description>
			<content:encoded><![CDATA[<p>This post contains the results of a Ruby shootout on Windows that I recently conducted. You can find the Mac edition, published last month, <a href="http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/">here</a>. I was planning to have this one ready much sooner, but a couple of serious events in personal life prevented that from happening. Be sure to grab <a href="http://feeds2.feedburner.com/ZenAndTheArtOfRubyProgramming">my feed</a> or <a href="http://antoniocangiano.us1.list-manage1.com/subscribe?u=9fd2908bf379ac3d3b9f2d8e3&#038;id=cec4240b96">join the newsletter</a> to avoid missing the upcoming Linux shootout.</p>
<p><strong>The setup</strong></p>
<p>For this shootout I included a subset of the <a href="http://github.com/acangiano/ruby-benchmark-suite">Ruby Benchmark Suite</a>. I opted to primarily exclude tests that were executed in fractions of a second in most VMs, focusing instead of more substantial benchmarks (several of which come from the Computer Language Benchmarks Game). The best times out of five runs are reported here for each benchmark.</p>
<p>All tests were run on Windows 7 x64, on an Intel Core 2 Quad Q6600 2.40 GHz, 8 GB DDR2 RAM, with two 500 GB 7200 rpm disks.</p>
<p>The implementations tested were:</p>
<ul>
<li><strong>Ruby 1.8.7</strong> (2010-01-10 patchlevel 249) [i386-mingw32] (RubyInstaller)</li>
<li><strong>Ruby 1.9.1 p378</strong> (2010-01-10 revision 26273) [i386-mingw32] (RubyInstaller)</li>
<li><strong>Ruby 1.9.2 dev</strong> (2010-05-31) [i386-mingw32] (experimental)</li>
<li><strong>JRuby 1.5.1</strong> (ruby 1.8.7 patchlevel 249) (2010-06-06 f3a3480) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20) [amd64-java]</li>
<li><strong>IronRuby 1.0</strong> x64 for .NET 4.0</li>
</ul>
<p>JRuby was run with the <code>--fast</code> and <code>--server</code> optimization flags.</p>
<p><strong>Disclaimer</strong></p>
<p>Synthetic benchmarks cannot predict how fast your programs will be when dealing with a particular implementation. They provide an (entertaining) educated guess, but <strong>you shouldn&#8217;t draw overly definitive conclusions from them</strong>. The values reported here should be assumed to be characteristic of server-side &#8211; and long running &#8211; processes and should be taken with a grain of salt.</p>
<p><strong>The results</strong></p>
<p>Please find below the execution times for the selected tests. Timeouts indicate that the execution of a single iteration for a given test took more than 60 seconds and had to be interrupted. Bold values indicate the best performance for each test.</p>
<p style="text-align: center;" align="center">
	<img src="http://programmingzen.com/wp-content/uploads/2010/06/rbs-win.png" alt="RBS Windows Shootout" />
</p>
<p><strong>Conclusions</strong></p>
<p>Despite a couple of errors and a few timeouts, JRuby was the fastest of the lot, which can be seen as impressive<del datetime="2010-07-04T02:18:01+00:00"> if we consider that this is Windows we are talking about after all</del>.</p>
<p>Ruby 1.9.1 and 1.9.2 were almost as fast as JRuby on these tests. With a few exceptions, the performances of the two 1.9 implementations were, expectedly, very similar.</p>
<p>JRuby, 1.9.1 and 1.9.2 were all faster than the current MRI implementation, which can be seen as a prerequisite as we move, as a community, away from Ruby 1.8. Finally, it&#8217;s worth noting that IronRuby&#8217;s performance was however in line with that of Ruby 1.8.7.</p>
<p><strong>Update (July 3, 2010)</strong>: The following box plot compares the various implementations for the tests for which all the implementations were successful. Only times for the largest successful input number were used in those tests where multiple input numbers were tested.</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/05/windows_shootout.png" alt="Windows Shootout Boxplot" /></p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Padrino: a Ruby framework built upon Sinatra</title>
		<link>http://programmingzen.com/2010/06/11/padrino-a-ruby-framework-built-upon-sinatra/</link>
		<comments>http://programmingzen.com/2010/06/11/padrino-a-ruby-framework-built-upon-sinatra/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 12:56:07 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1189</guid>
		<description><![CDATA[From the Padrino&#8217;s site: Padrino is a ruby framework built upon the excellent Sinatra Microframework. Sinatra is a DSL for creating simple web applications in Ruby with speed and minimal effort. This framework makes it as fun and easy as possible to code increasingly advanced web applications by expanding upon Sinatra while maintaining the spirit [...]]]></description>
			<content:encoded><![CDATA[<p>From the <a href="http://www.padrinorb.com/guides">Padrino&#8217;s site</a>:</p>
<blockquote><p>Padrino is a ruby framework built upon the excellent Sinatra Microframework. Sinatra is a DSL for creating simple web applications in Ruby with speed and minimal effort. This framework makes it as fun and easy as possible to code increasingly advanced web applications by expanding upon Sinatra while maintaining the spirit that made it great.</p></blockquote>
<p>The Ruby community has plenty of web frameworks at this point. Padrino &mdash; self-described as &#8220;The Elegant Ruby Web Framework&#8221;  &mdash; is interesting because it&#8217;s built on top of Sinatra, it&#8217;s highly modular, quite fast, and provides a drop-in admin interface. It fits between Sinatra and a large framework like Rails.</p>
<p><img src="http://antoniocangiano.com/wp-content/uploads/2010/06/padrino.png" align="right" style="float: right" alt="Padrino" hspace="5" />If it wasn&#8217;t for the fact that Rails 3 is about to be released, Padrino may have had a fighting chance at acquiring a good market share within the Ruby community. Rails 3 is here though, and it too is very modular and fast. Plus, it&#8217;s hard to beat the huge ecosystem that&#8217;s already built around it.</p>
<p>That said, the presence of an admin interface, a la Django, and the Sinatra core are definitely inviting features. Check out <a href="http://www.padrinorb.com/guides">their documentation</a> and <a href="http://www.padrinorb.com/guides/blog-tutorial">screencast</a>, to see if you think it&#8217;s worth considering for your own web development needs.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2010/06/11/padrino-a-ruby-framework-built-upon-sinatra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmarking MacRuby 0.6</title>
		<link>http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/</link>
		<comments>http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/#comments</comments>
		<pubDate>Sun, 16 May 2010 07:53:35 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Featured Article]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Benchmark Suite]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1168</guid>
		<description><![CDATA[Recently MacRuby 0.6 was released. The development team put a lot of emphasis on improving compatibility with Ruby 1.9, and the viability of MacRuby as a tool for developing Mac OS X applications. Focus on these aspects took precedence over performance, but I was still curious to see how well it performed when compared to [...]]]></description>
			<content:encoded><![CDATA[<p>Recently MacRuby 0.6 was released. The development team put a lot of emphasis on improving compatibility with Ruby 1.9, and the viability of MacRuby as a tool for developing Mac OS X applications. Focus on these aspects took precedence over performance, but I was still curious to see how well it performed when compared to Ruby 1.8.7 and Ruby 1.9, respectively.</p>
<p>This article showcases the results of a small Ruby shootout for Mac. I plan to publish a Windows one by next week, and then a week or two after that, a complete Linux shootout that will have many more implementations. Grab <a href="http://feeds2.feedburner.com/ZenAndTheArtOfRubyProgramming">my feed</a> or <a href="http://eepurl.com/xDb7">join the newsletter</a> to avoid missing upcoming shootout posts.</p>
<p><strong>The setup</strong></p>
<p>The tests are a large subset of the <a href="http://github.com/acangiano/ruby-benchmark-suite">Ruby Benchmark Suite</a>. Each test was run 10 times, five to detect the best execution time, and five to detect the minimal memory consumption. All of the tests were run on Mac OS X 10.6.3, on my MacBook Pro 2.66 GHz Intel Core 2 Duo, 4 GB 1067 MHz DDR3 RAM, 320 GB 7200 rpm disk.</p>
<p>Stable implementations tested:</p>
<ul>
<li>MacRuby 0.6</li>
<li>Ruby 1.8.7</li>
<li>Ruby 1.9.1</li>
</ul>
<p><strong>Disclaimer</strong></p>
<p>Synthetic benchmarks cannot predict how fast your programs will be with one implementation or another. They provide an (entertaining) educated guess, but <strong>you shouldn&#8217;t draw overly definitive conclusions from them</strong>. Furthermore, the Ruby Benchmark Suite has many tests that don&#8217;t provide much insight when it comes to comparing implementations. They are there for legacy reasons and will probably be removed in the future. For the time being, <strong>take them with a grain of salt</strong>.</p>
<p><strong>The results</strong></p>
<p>Without further hesitation, here are the execution times for the tests (divided in A-L, M-Z). Timeouts indicate that the execution of a single run took more than 60 seconds and had to be interrupted. Bold values indicate the best performance for each test.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://antoniocangiano.com/wp-content/uploads/2010/05/timeal1.png" alt="Time table A-L" /></p>
<p style="text-align: center;"><img class="aligncenter" src="http://antoniocangiano.com/wp-content/uploads/2010/05/timemz.png" alt="Time table M-Z" /></p>
<p>And here is the estimated memory usage:</p>
<p style="text-align: center;"><img class="aligncenter" src="http://antoniocangiano.com/wp-content/uploads/2010/05/spaceal.png" alt="Memory table A-L" /></p>
<p style="text-align: center;"><img class="aligncenter" src="http://antoniocangiano.com/wp-content/uploads/2010/05/spacemz.png" alt="Memory table M-Z" /></p>
<p><strong>Conclusions</strong></p>
<p>MacRuby 0.6 is faster than Ruby 1.9.1 at times, but it can also be significantly slower. Overall, as things stand now, its performance appears to be between that of Ruby 1.9.1 and Ruby 1.8.7, with several outliers and a greater variance compared to those two implementations. Memory wise, MacRuby appears to be significantly more &#8220;memory hungry&#8221; than the other implementations (even though this wasn&#8217;t all that much of a surprise to me).</p>
<p>I&#8217;m interested in seeing how future releases that will be focused more on performance will affect these preliminary results. For the time being however, don&#8217;t let this outcome discourage you from using MacRuby 0.6, which is the first release that&#8217;s considered stable for Mac OS X development.</p>
<p>Download: <a href="http://antoniocangiano.com/wp-content/uploads/2010/05/time-memory.zip">CSV Files</a></p>
<p>PS: If you are looking for a fun and easy way to get started with MacRuby, check out <a href="http://thinkcode.tv/catalog/introduction-macruby/">ThinkCode.TV&#8217;s screencast</a> on the subject.</p>
<p><strong>Update (July 3, 2010)</strong>: The following box plot compares the various implementations for the tests for which all the implementations were successful. Only times for the largest successful input number were used in those tests where multiple input numbers were tested.</p>
<p align="center"><img src="http://programmingzen.com/wp-content/uploads/2010/05/mac_shootout.png" alt="Mac Shootout Boxplot" /></p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Setup Ruby Enterprise Edition, nginx and Passenger (aka mod_rails) on Ubuntu</title>
		<link>http://programmingzen.com/2009/11/20/setup-ruby-enterprise-edition-nginx-and-passenger-aka-mod_rails-on-ubuntu/</link>
		<comments>http://programmingzen.com/2009/11/20/setup-ruby-enterprise-edition-nginx-and-passenger-aka-mod_rails-on-ubuntu/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 19:17:26 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1117</guid>
		<description><![CDATA[The following is a very short guide on setting up Ruby Enterprise Edition (REE), nginx and Passenger, for serving Ruby on Rails applications on Ubuntu. It also includes a few quick and easy optimization tips. We start with setting up REE (x64), using the .deb file provided by Phusion: wget http://rubyforge.org/frs/download.php/66163/ruby-enterprise_1.8.7-2009.10_amd64.deb sudo dpkg -i ruby-enterprise_1.8.7-2009.10_amd64.deb [...]]]></description>
			<content:encoded><![CDATA[<p>The following is a very short guide on setting up Ruby Enterprise Edition (REE), nginx and Passenger, for serving Ruby on Rails applications on Ubuntu. It also includes a few quick and easy optimization tips.</p>
<p>We start with setting up REE (x64), using the .deb file provided by Phusion:</p>
<div class="highlight">
<pre>wget http://rubyforge.org/frs/download.php/66163/ruby-enterprise_1.8.7-2009.10_amd64.deb
sudo dpkg -i ruby-enterprise_1.8.7-2009.10_amd64.deb
ruby -v
</pre>
</div>
<p>In output you should see &#8220;ruby 1.8.7 (2009-06-12 patchlevel 174)&#8230;&#8221; or similar. If this is the case, good; while you are there, update RubyGems and the installed gems:</p>
<div class="highlight">
<pre>sudo gem update --system
sudo gem update
</pre>
</div>
<p>Next, you&#8217;ll need to install nginx, which is a really fast web server. The <a href="http://phusion.nl/about.html">Phusion</a> team has made it very easy to install, but if you simply follow most instructions found elsewhere, you&#8217;ll get the following error:</p>
<pre>checking for system md library ... not found
checking for system md5 library ... not found
checking for OpenSSL md5 crypto library ... not found

./configure: error: the HTTP cache module requires md5 functions
from OpenSSL library.  You can either disable the module by using
--without-http-cache option, or install the OpenSSL library in the
system,
or build the OpenSSL library statically from the source with nginx by
using
--with-http_ssl_module --with-openssl=
<path> options.</pre>
<p>Instead, we are going to install libssl-dev first and then nginx and its Passenger module:</p>
<div class="highlight">
<pre>sudo aptitude install libssl-dev
sudo passenger-install-nginx-module
</pre>
</div>
<p>Follow the prompt and accept all the defaults (when prompted to chose between 1 and 2, pick 1).</p>
<p>Before I proceed with the configuration, I like to create an init script and have it boot at startup (the script itself is adapted from one provided by the excellent <a href="http://articles.slicehost.com">articles at slicehost.com</a>):</p>
<div class="highlight">
<pre>sudo vim /etc/init.d/nginx
</pre>
</div>
<p>The content of which needs to be:</p>
<div class="highlight">
<pre><span class="c">#! /bin/sh</span>

<span class="c">### BEGIN INIT INFO</span>
<span class="c"># Provides:          nginx</span>
<span class="c"># Required-Start:    $all</span>
<span class="c"># Required-Stop:     $all</span>
<span class="c"># Default-Start:     2 3 4 5</span>
<span class="c"># Default-Stop:      0 1 6</span>
<span class="c"># Short-Description: starts the nginx web server</span>
<span class="c"># Description:       starts nginx using start-stop-daemon</span>
<span class="c">### END INIT INFO</span>

<span class="nv">PATH</span><span class="o">=</span>/opt/nginx/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
<span class="nv">DAEMON</span><span class="o">=</span>/opt/nginx/sbin/nginx
<span class="nv">NAME</span><span class="o">=</span>nginx
<span class="nv">DESC</span><span class="o">=</span>nginx

<span class="nb">test</span> -x <span class="nv">$DAEMON</span> <span class="o">||</span> <span class="nb">exit </span>0

<span class="c"># Include nginx defaults if available</span>
<span class="k">if</span> <span class="o">[</span> -f /etc/default/nginx <span class="o">]</span> ; <span class="k">then</span>
    . /etc/default/nginx
<span class="k">fi</span>

<span class="nb">set</span> -e

. /lib/lsb/init-functions

<span class="k">case</span> <span class="s2">&quot;$1&quot;</span> in
  start<span class="o">)</span>
    <span class="nb">echo</span> -n <span class="s2">&quot;Starting $DESC: &quot;</span>
    start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/<span class="nv">$NAME</span>.pid <span class="se">\</span>
        --exec <span class="nv">$DAEMON</span> -- <span class="nv">$DAEMON_OPTS</span> <span class="o">||</span> <span class="nb">true</span>
<span class="nb">    echo</span> <span class="s2">&quot;$NAME.&quot;</span>
    ;;
  stop<span class="o">)</span>
    <span class="nb">echo</span> -n <span class="s2">&quot;Stopping $DESC: &quot;</span>
    start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/<span class="nv">$NAME</span>.pid <span class="se">\</span>
        --exec <span class="nv">$DAEMON</span> <span class="o">||</span> <span class="nb">true</span>
<span class="nb">    echo</span> <span class="s2">&quot;$NAME.&quot;</span>
    ;;
  restart|force-reload<span class="o">)</span>
    <span class="nb">echo</span> -n <span class="s2">&quot;Restarting $DESC: &quot;</span>
    start-stop-daemon --stop --quiet --pidfile <span class="se">\</span>
        /opt/nginx/logs/<span class="nv">$NAME</span>.pid --exec <span class="nv">$DAEMON</span> <span class="o">||</span> <span class="nb">true</span>
<span class="nb">    </span>sleep 1
    start-stop-daemon --start --quiet --pidfile <span class="se">\</span>
        /opt/nginx/logs/<span class="nv">$NAME</span>.pid --exec <span class="nv">$DAEMON</span> -- <span class="nv">$DAEMON_OPTS</span> <span class="o">||</span> <span class="nb">true</span>
<span class="nb">    echo</span> <span class="s2">&quot;$NAME.&quot;</span>
    ;;
  reload<span class="o">)</span>
      <span class="nb">echo</span> -n <span class="s2">&quot;Reloading $DESC configuration: &quot;</span>
      start-stop-daemon --stop --signal HUP --quiet --pidfile /opt/nginx/logs/<span class="nv">$NAME</span>.pid <span class="se">\</span>
          --exec <span class="nv">$DAEMON</span> <span class="o">||</span> <span class="nb">true</span>
<span class="nb">      echo</span> <span class="s2">&quot;$NAME.&quot;</span>
      ;;
  status<span class="o">)</span>
      status_of_proc -p /opt/nginx/logs/<span class="nv">$NAME</span>.pid <span class="s2">&quot;$DAEMON&quot;</span> nginx <span class="o">&amp;&amp;</span> <span class="nb">exit </span>0 <span class="o">||</span> <span class="nb">exit</span> <span class="nv">$?</span>
      ;;
  *<span class="o">)</span>
    <span class="nv">N</span><span class="o">=</span>/etc/init.d/<span class="nv">$NAME</span>
    <span class="nb">echo</span> <span class="s2">&quot;Usage: $N {start|stop|restart|reload|force-reload|status}&quot;</span> &gt;&amp;2
    <span class="nb">exit </span>1
    ;;
<span class="k">esac</span>

<span class="nb">exit </span>0
</pre>
</div>
<p>Change its permission and have it startup at boot:</p>
<div class="highlight">
<pre>sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults
</pre>
</div>
<p>From now on, you&#8217;ll be able to start, stop and restart nginx with it. Start the server as follows:</p>
<div class="highlight">
<pre>sudo /etc/init.d/nginx start
</pre>
</div>
<p>Heading over to your server IP with your browser, you should see &#8220;Welcome to nginx!&#8221;. If you do, great, we can move on with the configuration of nginx for your Rails app.</p>
<p>Edit nginx&#8217; configuration file:</p>
<div class="highlight">
<pre>sudo vim /opt/nginx/conf/nginx.conf
</pre>
</div>
<p>Adding a server section within the http section, as follows:</p>
<div class="highlight">
<pre>    server <span class="o">{</span>
        listen 80;
        server_name example.com;
        root /somewhere/my_rails_app/public;
        passenger_enabled on;
        rails_spawn_method smart;
    <span class="o">}</span>
</pre>
</div>
<p>The server name can also be a subdomain if you wish (e.g., blog.example.com). It&#8217;s important that you point the root to your Rails&#8217; app public directory.</p>
<p>The rails_spawn_method directive is very efficient, allowing Passenger to consume less memory per process and speed up the spawning process, whenever your Rails application is not affected by its limitations (for a discussion about this you can read the proper <a href="http://www.modrails.com/documentation/Users%20guide.html#_the_smart_spawning_method">section in the official guide</a>).</p>
<p>If you have lots of RAM (e.g., more than 512 MB) on your server, you may want to consider increasing you maximum pool size, with the directive passenger_max_pool_size from its default size of 6. Conversely, if you want to limit the number of processes running at any time and consume less memory on a small VPS (e.g., 128 to 256MB), you can decrease that number down to 2 (or something in that range). (Always test a bunch of configurations to find one that works for you). You can read more about this directive, <a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerMaxPoolSize">in the official guide</a>.</p>
<p>While you are modifying nginx&#8217; configuration, you may also want to increase the worker processes (e.g., to 4, on a typical VPS) and add a few more tweaks (such as enabling gzip compression):</p>
<div class="highlight">
<pre><span class="c"># ...</span>
http <span class="o">{</span>
    passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.5;
    passenger_ruby /usr/local/bin/ruby;

    include       mime.types;
    default_type  application/octet-stream;

    access_log  logs/access.log;

    sendfile        on;
    keepalive_timeout  65;
    tcp_nodelay on;

    gzip on;
    gzip_comp_level 2;
    gzip_proxied any;   

    server <span class="o">{</span>
    <span class="c">#...</span>
</pre>
</div>
<p>When you are happy with the changes, save the file, and restart nginx:</p>
<div class="highlight">
<pre>sudo /etc/init.d/nginx restart
</pre>
</div>
<p>If you wish to restart Passenger in the future, without having to restart the whole web server, you can simply run the following command:</p>
<div class="highlight">
<pre>touch /somewhere/my_rails_app/tmp/restart.txt
</pre>
</div>
<p>Passenger also provides a few handy monitoring tools. Check them out:</p>
<div class="highlight">
<pre>sudo passenger-status
sudo passenger-memory-stats
</pre>
</div>
<p>That&#8217;s it, you are ready to go! I hope that you find these few notes useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2009/11/20/setup-ruby-enterprise-edition-nginx-and-passenger-aka-mod_rails-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Getting MacRuby&#8217;s compiler to work</title>
		<link>http://programmingzen.com/2009/10/08/getting-macrubys-compiler-to-work/</link>
		<comments>http://programmingzen.com/2009/10/08/getting-macrubys-compiler-to-work/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 20:45:13 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1107</guid>
		<description><![CDATA[There is major news in Rubyland today. MacRuby&#8217;s team just released their fist beta of version 0.5 (an experimental, still incomplete version of Ruby), which brings JIT, removal of the dreaded GIL (Global Interpreter Lock), native threads, GCD (Grand Central Dispatch) for multicore computing, and a whole new set of features found in the release [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://antoniocangiano.com/wp-content/uploads/2009/10/macruby_logo.png" align="right" alt="MacRuby's logo" />There is major news in Rubyland today. MacRuby&#8217;s team just released their fist beta of version 0.5 (an experimental, still incomplete version of Ruby), which brings JIT, removal of the dreaded GIL (Global Interpreter Lock), native threads, GCD (Grand Central Dispatch) for multicore computing, and a whole new set of features found in <a href="http://www.macruby.org/blog/2009/10/07/macruby05b1.html">the release announcement</a> to the table.</p>
<p>The most important new feature is the presence of a compiler. That&#8217;s right, thanks to this release, Ruby code can now become highly optimized executable code. How awesome is that? I can sense that you&#8217;re pumped by this news, so why not head over to MacRuby.com and <a href="http://www.macruby.org/downloads.html">download the installation file</a> for yourself? After you&#8217;ve done that, the next thing you&#8217;re going to want to do is run a small test like the following:</p>
<div class="highlight">
<pre><span class="nv">$ </span>macrubyc world_domination.rb -o world_domination
<span class="s1">Can&#39;t locate program `llc&#39;</span>
</pre>
</div>
<p>Oh noes! llc is a tool that ships with the LLVM (upon which MacRuby is built), however it&#8217;s not included with MacRuby&#8217;s installer (it will be in the future). But fear not my friends, there is a solution:</p>
<div class="highlight">
<pre><span class="nv">$ </span>svn co -r 82747 https://llvm.org/svn/llvm-project/llvm/trunk llvm-trunk
<span class="nv">$ </span><span class="nb">cd </span>llvm-trunk
<span class="nv">$ </span>./configure
<span class="nv">$ UNIVERSAL</span><span class="o">=</span>1 <span class="nv">UNIVERSAL_ARCH</span><span class="o">=</span><span class="s2">&quot;i386 x86_64&quot;</span> <span class="nv">ENABLE_OPTIMIZED</span><span class="o">=</span>1 make -j2
<span class="nv">$ </span>sudo env <span class="nv">UNIVERSAL</span><span class="o">=</span>1 <span class="nv">UNIVERSAL_ARCH</span><span class="o">=</span><span class="s2">&quot;i386 x86_64&quot;</span> <span class="nv">ENABLE_OPTIMIZED</span><span class="o">=</span>1 make install
</pre>
</div>
<p>If your machine does not have 2 cores, remove the -j2 option from the fourth line or adjust the number accordingly.</p>
<p>The compilation phase may take a couple of centuries, depending on your machine&#8217;s speed, but it should eventually build the LLVM. <img src='http://programmingzen.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  llc will be placed in your PATH, and you&#8217;ll finally be able to compile Ruby code and obtain an executable to help you carry out your world domination plans.</p>
<div class="highlight">
<pre><span class="nv">$ </span>macrubyc world_domination.rb -o world_domination
<span class="nv">$ </span>./world_domination
MUAHAHAHAHA!
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2009/10/08/getting-macrubys-compiler-to-work/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Improve the speed and security of your SQL queries</title>
		<link>http://programmingzen.com/2009/09/09/improve-the-speed-and-security-of-your-sql-queries/</link>
		<comments>http://programmingzen.com/2009/09/09/improve-the-speed-and-security-of-your-sql-queries/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 05:15:38 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[DB2]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1101</guid>
		<description><![CDATA[An easy way to improve the performance and security of SQL queries is to replace literals with parameters. By replacing literal values with parameters, advanced relational databases will be able to compile your queries and have their execution plans cached. This saves time and precious resources when the same query (minus the actual values) is executed [...]]]></description>
			<content:encoded><![CDATA[<p>An easy way to improve the performance and security of SQL queries is to replace literals with parameters. By replacing literal values with parameters, advanced relational databases will be able to compile your queries and have their execution plans cached. This saves time and precious resources when the same query (minus the actual values) is executed over and over.</p>
<p>Consider the following series of queries:</p>
<div class="highlight">
<pre><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">100</span> <span class="k">AND</span> <span class="mi">499</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">500</span> <span class="k">AND</span> <span class="mi">999</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">1000</span> <span class="k">AND</span> <span class="mi">1999</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">2000</span> <span class="k">AND</span> <span class="mi">4999</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">5000</span> <span class="k">AND</span> <span class="mi">9999</span><span class="p">;</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="mi">10000</span> <span class="k">AND</span> <span class="mi">50000</span><span class="p">;</span></pre>
</div>
<p>These each represent the same query and can be transformed into a single parameterized query:</p>
<div class="highlight">
<pre><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">karma</span> <span class="k">BETWEEN</span> <span class="o">?</span> <span class="k">AND</span> <span class="o">?</span><span class="p">;</span></pre>
</div>
<p>Trying to use clever tricks with quotes in order to inject arbitrary SQL code becomes futile. Parameters are considered values, and have no effect on the structure of the query itself.</p>
<p>Parameterized queries are therefore efficient and go a long way towards preventing SQL injection attacks in your applications. They have virtually no downside.</p>
<p>Newbie developers often ignore the existence of this feature and end up irritating seasoned DBAs who have to deal with the consequences of their incompetence. <a href="http://freedb2.com/2009/09/08/the-article-every-dba-should-forward-to-sql-developers/">Leon Katsnelson argues</a> that this is such an important matter, that every DBA should forward <a href="http://www.computerworld.com/s/article/9137478/Opinion_No_more_excuses_for_SQL_injection_attacks">this Computerworld article</a> to their developers. I tend to agree with how important of an issue that is.</p>
<p>That article provides the following example in Java:</p>
<div class="highlight">
<pre><span class="n">String</span> <span class="n">lastName</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="na">getParameter</span><span class="o">(</span><span class="s">"lastName"</span><span class="o">);</span>
<span class="n">String</span> <span class="n">query</span> <span class="o">=</span> <span class="s">"select * from customers where last_name = ?"</span>
<span class="n">PreparedStatement</span> <span class="n">pstmt</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="na">prepareStatement</span><span class="o">(</span><span class="n">query</span><span class="o">);</span>
<span class="n">pstmt</span><span class="o">.</span><span class="na">setString</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">lastName</span><span class="o">);</span>
<span class="k">try</span> <span class="o">{</span> <span class="n">ResultSet</span> <span class="n">results</span> <span class="o">=</span> <span class="n">pstmt</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span> <span class="o">}</span></pre>
</div>
<p>Here I&#8217;ll show you an example of how to work with parameterized queries from Ruby and Python. I&#8217;ll use the Ruby and Python drivers for <a href="http://www.ibm.com/software/data/db2/express/download.html?S_CMP=ECDDWW01&amp;S_TACT=ACDB201">DB2</a>.</p>
<p>Ruby first:</p>
<div class="highlight">
<pre><span class="nb">require</span> <span class="s1">'ibm_db'</span>

<span class="n">conn</span> <span class="o">=</span> <span class="no">IBM_DB</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">"mydb"</span><span class="p">,</span> <span class="s2">"db2inst1"</span><span class="p">,</span> <span class="s2">"mypassword"</span><span class="p">)</span>

<span class="n">query</span> <span class="o">=</span> <span class="s2">"SELECT * FROM users WHERE karma BETWEEN ? AND ?"</span>
<span class="n">pstmt</span> <span class="o">=</span> <span class="no">IBM_DB</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">query</span><span class="p">)</span>

<span class="n">values</span> <span class="o">=</span> <span class="o">[</span><span class="mi">500</span><span class="p">,</span> <span class="mi">999</span><span class="o">]</span>
<span class="no">IBM_DB</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">pstmt</span><span class="p">,</span> <span class="n">values</span><span class="p">)</span>

<span class="k">while</span> <span class="n">row</span> <span class="o">=</span> <span class="no">IBM_DB</span><span class="o">.</span><span class="n">fetch_array</span><span class="p">(</span><span class="n">pstmt</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="n">row</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="s2">:</span><span class="si">#{</span><span class="n">row</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span></pre>
</div>
<p>We load the driver (use <code>mswin32/ibm_db</code> on Windows, and <code>ibm_db.bundle</code> on Mac), create a prepared statement, and then bind the two parameter values to it through the <code>execute</code> method. We then fetch the resultset one row at a time and print the value of the first two fields for each record. For fine-tuned control we could have used the <a href="http://rubyibm.rubyforge.org/docs/driver/0.9.0/rdoc/classes/IBM_DB.html#M000005">IBM_DB::bind_param</a> method.</p>
<p>The Python version is very similar:</p>
<div class="highlight">
<pre><span class="kn">import</span> <span class="nn">ibm_db</span>

<span class="n">conn</span> <span class="o">=</span> <span class="n">ibm_db</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"mydb"</span><span class="p">,</span> <span class="s">"db2inst1"</span><span class="p">,</span> <span class="s">"mypassword"</span><span class="p">)</span>

<span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT * FROM users WHERE karma BETWEEN ? AND ?"</span>
<span class="n">pstmt</span> <span class="o">=</span> <span class="n">ibm_db</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">query</span><span class="p">)</span>

<span class="n">values</span> <span class="o">=</span> <span class="p">(</span><span class="mf">500</span><span class="p">,</span> <span class="mf">999</span><span class="p">)</span>
<span class="n">ibm_db</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">pstmt</span><span class="p">,</span> <span class="n">values</span><span class="p">)</span>

<span class="nb">tuple</span> <span class="o">=</span> <span class="n">ibm_db</span><span class="o">.</span><span class="n">fetch_tuple</span><span class="p">(</span><span class="n">pstmt</span><span class="p">)</span>
<span class="k">while</span> <span class="nb">tuple</span><span class="p">:</span>
    <span class="k">print</span> <span class="nb">tuple</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">":"</span> <span class="o">+</span> <span class="nb">tuple</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
    <span class="nb">tuple</span> <span class="o">=</span> <span class="n">ibm_db</span><span class="o">.</span><span class="n">fetch_tuple</span><span class="p">(</span><span class="n">pstmt</span><span class="p">)</span></pre>
</div>
<p>As you can see, working with parameterized queries is not any harder than dynamically generating SQL queries. Yet the benefits of doing so are huge.</p>
<p>Unfortunately, despite being a very sound choice to base an Object-Relational Mapper (ORM) on, ActiveRecord does not use parameterized queries. Even when it looks like you are passing parameters to a given method, these are actually used to dynamically form an SQL query. Of course you are still free to use parameterized queries in your Rails applications by employing the driver directly. But I really think this is something ActiveRecord should be built upon.</p>
<p>Luckily for Django developers, Django&#8217;s ORM uses parameterized queries, thus improving both performance and security with a single design choice. In the Python world you couldn&#8217;t get away with ignoring parameterized queries.</p>
<p>For those of you using Rails, all is not lost. <a href="http://www.ibm.com/software/data/db2/express/download.html?S_CMP=ECDDWW01&amp;S_TACT=ACDB201">DB2 Express-C 9.7</a> has a killer feature known as the <a href="http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.wn.doc/doc/c0054005.html">Statement Concentrator</a>, which caches similar queries allowing them to use a shared access plan. It&#8217;s not as efficient as using prepared statements in your code, but it&#8217;s the best you can do when, as in the case of ActiveRecord, you can&#8217;t use parameterized queries directly. <a href="http://freedb2.com/2009/09/08/the-article-every-dba-should-forward-to-sql-developers/">Leon&#8217;s article</a> explains in greater detail how this feature actually works.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2009/09/09/improve-the-speed-and-security-of-your-sql-queries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Installing the Ruby driver for DB2 on Mac OS X Snow Leopard</title>
		<link>http://programmingzen.com/2009/09/03/installing-the-ruby-driver-for-db2-on-mac-os-x-snow-leopard/</link>
		<comments>http://programmingzen.com/2009/09/03/installing-the-ruby-driver-for-db2-on-mac-os-x-snow-leopard/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 19:23:35 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[DB2]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1097</guid>
		<description><![CDATA[Now that Mac OS X 10.6 is out, it&#8217;s time to leave the world of 32 bit computing behind. The pre-installed Ruby interpreter will run in 64 bit mode by default, so you may need to pay attention when installing some C-based gems. The ibm_db Ruby gem for DB2 can easily be installed or updated [...]]]></description>
			<content:encoded><![CDATA[<p>Now that Mac OS X 10.6 is out, it&#8217;s time to leave the world of 32 bit computing behind. The pre-installed Ruby interpreter will run in 64 bit mode by default, so you may need to pay attention when installing some C-based gems. The ibm_db Ruby gem for DB2 can easily be installed or updated to the latest available version by following these simple steps:</p>
<div class="highlight">
<pre><span class="nv">$ </span>sudo -s
<span class="nv">$ </span><span class="nb">export </span><span class="nv">IBM_DB_LIB</span><span class="o">=</span>/Users/&lt;username&gt;/sqllib/lib64
<span class="nv">$ </span><span class="nb">export </span><span class="nv">IBM_DB_INCLUDE</span><span class="o">=</span>/Users/&lt;username&gt;/sqllib/include
<span class="nv">$ </span><span class="nb">export </span><span class="nv">ARCHFLAGS</span><span class="o">=</span><span class="s2">&quot;-arch x86_64&quot;</span>
<span class="nv">$ </span>gem install ibm_db
</pre>
</div>
<p>You can verify that the installation was successful my running the following:</p>
<div class="highlight">
<pre><span class="nv">$</span> <span class="n">irb</span>
<span class="o">&gt;&gt;</span> <span class="nb">require</span> <span class="s1">&#39;ibm_db.bundle&#39;</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</pre>
</div>
<p>Please let me know if you encounter any issues, I&#8217;d be glad to help you.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2009/09/03/installing-the-ruby-driver-for-db2-on-mac-os-x-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recommended Ruby and Rails books (August 2009)</title>
		<link>http://programmingzen.com/2009/08/24/recommended-ruby-and-rails-books/</link>
		<comments>http://programmingzen.com/2009/08/24/recommended-ruby-and-rails-books/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 12:46:10 +0000</pubDate>
		<dc:creator>Antonio Cangiano</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Merb]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://antoniocangiano.com/?p=1087</guid>
		<description><![CDATA[I finally got around to updating the Ruby and Rails book pages. The existing list was getting a bit obsolete and I didn&#8217;t like the idea of recommending old books to newcomers. I also had some interesting new entries. Without further ado: Recommended Ruby Books Recommended Rails Books A few people may disagree with the [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to updating the Ruby and Rails book pages. The existing list was getting a bit obsolete and I didn&#8217;t like the idea of recommending old books to newcomers. I also had some interesting new entries.</p>
<p>Without further ado:</p>
<ul>
<li><big><a href="http://antoniocangiano.com/ruby-and-rails-recommended-books/">Recommended Ruby Books</a></big></li>
<li><big><a href="http://antoniocangiano.com/rails-books/">Recommended Rails Books</a></big></li>
</ul>
<p>A few people may disagree with the choices, but I think most experienced Ruby and Rails programmers, who&#8217;ve read those books, will concur with my recommendations. I&#8217;m quite confident that these are, all things considered, some of the best books available on the subject.</p>
<p><strong>A word to the publishers</strong></p>
<p>As tempting as it is to collect Ruby and Rails books, these days I don&#8217;t feel I can economically justify the act of purchasing every Ruby or Rails book put out there. So if you are a publisher or an author, and you&#8217;d like for me to consider your book, you are certainly welcome to <a href="mailto:info@antoniocangiano.com?subject=Review copy">send me a review copy</a>. I will definitely read it, but only include it on these lists if it&#8217;s either outstanding or as good as the existing ones. If it&#8217;s a programming book that&#8217;s not related to Ruby/Rails, yet is really good, I would consider reviewing it on my blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmingzen.com/2009/08/24/recommended-ruby-and-rails-books/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
