<?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>Curia &#187; F/OSS</title>
	<atom:link href="http://blog.curiasolutions.com/category/foss/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.curiasolutions.com</link>
	<description>Technology thoughts and ideas</description>
	<lastBuildDate>Mon, 12 Dec 2011 00:55:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>An rsync-like interface for Amazon S3 and Google Storage</title>
		<link>http://blog.curiasolutions.com/2011/12/an-rsync-like-interface-for-amazon-s3-and-google-storage/</link>
		<comments>http://blog.curiasolutions.com/2011/12/an-rsync-like-interface-for-amazon-s3-and-google-storage/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 00:55:06 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[boto]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=1101</guid>
		<description><![CDATA[Every so often I find myself working on that odd job that requires syncing files with Amazon&#8217;s S3. In the beginning, I tried some of the various S3 FUSE interfaces—hoping for something that would play nice with rsync—but FUSE&#8217;s stability always left something to be desired and more often than not I&#8217;d be left with [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2011/12/an-rsync-like-interface-for-amazon-s3-and-google-storage/' addthis:title='An rsync-like interface for Amazon S3 and Google Storage ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>Every so often I find myself working on that odd job that requires syncing files with Amazon&#8217;s S3. In the beginning, I tried some of the various S3 FUSE interfaces—hoping for something that would play nice with rsync—but FUSE&#8217;s stability always left something to be desired and more often than not I&#8217;d be left with that one transfer that never would quite finish correctly.</p>
<p>Eventually I discovered <a href="http://github.com/boto/boto" target="_blank">boto</a> and settled in to using a crude (yet stable) Python/boto solution for these type of tasks—all the while wondering why nobody took the time to write a &#8220;real&#8221; rsync-like client for S3.</p>
<p>Well, this last time around I finally decided to stop whining and take matters into my own hands. After a couple of late nights fleshing out my basic boto solutions, I&#8217;m happy to announce what I&#8217;m calling &#8220;boto rsync&#8221;—an rsync like wrapper for boto&#8217;s cloud storage interfaces (S3 <em>and</em> Google Storage).</p>
<p>Please take a look at the project on github and let me know what you think: <a href="http://github.com/seedifferently/boto_rsync" target="_blank">http://github.com/seedifferently/boto_rsync</a></p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2011/12/an-rsync-like-interface-for-amazon-s3-and-google-storage/' addthis:title='An rsync-like interface for Amazon S3 and Google Storage ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2011/12/an-rsync-like-interface-for-amazon-s3-and-google-storage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The long overdue &#8220;Shootout&#8221; update</title>
		<link>http://blog.curiasolutions.com/2011/09/the-long-overdue-shootout-update/</link>
		<comments>http://blog.curiasolutions.com/2011/09/the-long-overdue-shootout-update/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 19:08:06 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[pyramid]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=1079</guid>
		<description><![CDATA[It&#8217;s been several months since I&#8217;ve had a chance to update The Great Web Framework Shootout, but this weekend I decided that it was time to dig in and freshen things up a bit. Not only have most of the frameworks seen new releases since the last revision, but I finally decided to move all [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2011/09/the-long-overdue-shootout-update/' addthis:title='The long overdue &#8220;Shootout&#8221; update ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been several months since I&#8217;ve had a chance to update <em><a title="The Great Web Framework Shootout" href="http://blog.curiasolutions.com/the-great-web-framework-shootout/">The Great Web Framework Shootout</a></em>, but this weekend I decided that it was time to dig in and freshen things up a bit.</p>
<p>Not only have most of the frameworks seen new releases since the last revision, but I finally decided to move all of the tests over to Amazon&#8217;s &#8220;release&#8221; version of the Ubuntu LTS AMI.</p>
<p>Below is a quick summary of what&#8217;s new in this revision:</p>
<ul>
<li>All tests were performed on the updated Ubuntu LTS AMI (ami-fbbf7892 ubuntu-images-us/ubuntu-lucid-10.04-amd64-server-20110719.manifest.xml)</li>
<li>The updated AMI was configured with Python 2.6.5, PHP 5.3.2, Ruby 1.9.2p290, Apache 2.2.14 (default config), mod_wsgi 2.8 (embedded mode), and mod_passenger 3.0.9</li>
<li>Rails 2.x and 3.0 were dropped from the &#8220;full stack(ish)&#8221; tests in favor of Rails 3.1.</li>
<li>CakePHP 1.2 was dropped from the PHP tests in favor of 1.3, but Symfony and Yii were added as they seem to have considerable market share.</li>
<li>CakePHP&#8217;s caching engine was incorrectly configured during the last round of tests, and this has been corrected.</li>
</ul>
<p><a href="http://profiles.google.com/seedifferently" target="_blank">Circle me on Google+</a> to keep track of further updates, and feel free to contact me there with any questions or comments.</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2011/09/the-long-overdue-shootout-update/' addthis:title='The long overdue &#8220;Shootout&#8221; update ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2011/09/the-long-overdue-shootout-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The great web technology shootout – Round 4: Pyramid vs Django vs TG vs Rails 2 &amp; 3</title>
		<link>http://blog.curiasolutions.com/2010/11/the-great-web-technology-shootout-%e2%80%93-round-4-pyramid-vs-django-vs-tg-vs-rails-2-3/</link>
		<comments>http://blog.curiasolutions.com/2010/11/the-great-web-technology-shootout-%e2%80%93-round-4-pyramid-vs-django-vs-tg-vs-rails-2-3/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 00:00:06 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pyramid]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=915</guid>
		<description><![CDATA[[Due to the popularity of these posts, I have decided to move all the benchmarking information over to its own dedicated page. Please see the new framework shootout page for the latest information.] [Note: This post is the continuation of a series. Please read Round 1, Round 2, and Round 3 first if you are just [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2010/11/the-great-web-technology-shootout-%e2%80%93-round-4-pyramid-vs-django-vs-tg-vs-rails-2-3/' addthis:title='The great web technology shootout – Round 4: Pyramid vs Django vs TG vs Rails 2 &#38; 3 ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><strong>[Due to the popularity of these posts, I have decided to move all the benchmarking information over to its own dedicated page. Please see the new <a href="http://blog.curiasolutions.com/?p=963">framework shootout page</a> for the latest information.]</strong></p>
<p>[Note: This post is the continuation of a series. Please read <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>, <a href="http://blog.curiasolutions.com/?p=278">Round 2</a>, and <a href="http://blog.curiasolutions.com/?p=409">Round 3</a> first if you are just now joining us.]</p>
<p>While I had originally intended for round 4 to showcase how microframeworks are changing the way we do &#8220;quick and dirty&#8221; web development (and how they make using PHP as &#8220;an extension to HTML&#8221; old hat), my current programming habits have kept me involved in the more &#8220;full-stack&#8221; framework solutions. So, rather than spitting out various benchmarks of frameworks that I have little or no interaction with, and since enough time has passed since the last &#8220;shootout&#8221; that the landscape has changed a bit (with the introduction of <a href="http://docs.pylonshq.com/" target="_blank">Pyramid</a> and the release of Rails 3), I have instead decided to showcase the most recent data on the frameworks that I personally find myself in contact with on a regular basis. <span id="more-915"></span></p>
<p>&nbsp;</p>
<blockquote>
<h4>Warning: Everything is different this time around!</h4>
</blockquote>
<p>These benchmarks were all run on a fresh Amazon EC2 instance in order to (hopefully) achieve a more isolated environment. Obviously, since these benchmarks have all been run on a completely different box than any of the previous rounds, no previous data should be compared with these numbers.</p>
<p><strong>What you should know about Round 4:</strong></p>
<ul>
<li>The EC2 instance used was: ami-da0cf8b3 m1.large ubuntu-images-us/ubuntu-lucid-10.04-amd64-server-20101020.manifest.xml</li>
<li>As a &#8220;Large&#8221; instance, Amazon describes the resources as: 7.5 GB of memory, 4 EC2 Compute Units (2 virtual cores with 2 EC2 Compute Units each), 850 GB of local instance storage, 64-bit platform.</li>
<li>The various system software used was whatever was current as of November 18, 2010 on Ubuntu 10.04&#8242;s repositories.</li>
<li>Apache 2.2.14 was used for all tests.</li>
<li>Python 2.6.5 and mod_wsgi 3.3 (embedded mode) were used for the Python tests.</li>
<li>Ruby 1.8.7 (except for the last Rails 3 test) and Phusion Passenger 3.0 were used for the Rails tests.</li>
<li>ApacheBench was run with -n 10000 and -c 10 about 5-10 times each, and the &#8220;best guess average&#8221; was chosen (yeah, I&#8217;m lazy).</li>
<li>The Pyramid/TG test apps used SQLAlchemy as the ORM and Jinja2 as the templating system (Jinja2 was consistently around 25-50r/s faster than Mako for me).</li>
</ul>
<p>&nbsp;</p>
<p>Remember, nothing here is really all that scientific and your mileage WILL vary. Now on to the results&#8230;</p>
<p>&nbsp;</p>
<blockquote>
<h4>The &#8220;Hello World&#8221; string test</h4>
</blockquote>
<p>The &#8220;Hello World&#8221; string test simply spits out a string response. There&#8217;s no template or DB calls involved, so the level of processing should be minimal.</p>
<div id="attachment_534" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hello.png"><img class="size-full wp-image-531" title="Hello World Test" src="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hello.png" alt="The return hello world test chart" width="556" height="344" /></a><p class="wp-caption-text">The return hello world test chart</p></div>
<p>&nbsp;</p>
<blockquote>
<h4>The template test</h4>
</blockquote>
<p>The template test simply spits out Lorem Ipsum via a template (thus engaging the framework&#8217;s templating systems).</p>
<div id="attachment_535" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hellos.png"><img class="size-full wp-image-531" title="The template test chart" src="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hellos.png" alt="The template test chart" width="556" height="344" /></a><p class="wp-caption-text">The template test chart</p></div>
<p>&nbsp;</p>
<blockquote>
<h4>The template + DB query test</h4>
</blockquote>
<p>The template/db test simply loads 5 rows of Lorem Ipsum from a SQLite DB and spits it out via a template (thus engaging both the framework&#8217;s ORM and templating system).</p>
<div id="attachment_536" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hellodb.png"><img class="size-full wp-image-531" title="Template test with database query" src="http://blog.curiasolutions.com/wp-content/uploads/2010/11/round_4_hellodb.png" alt="Template test with database query" width="556" height="344" /></a><p class="wp-caption-text">Template test with database query</p></div>
<p>&nbsp;</p>
<blockquote>
<h4>Closing thoughts</h4>
</blockquote>
<ul>
<li>The Pyramid Alpha results excite me quite a bit with all the talk of the various frameworks looking to merge with it. Could this really become the &#8220;one Python framework to rule them all&#8221;?</li>
<li>Django is still going strong, and continues to be an exceptional choice if you&#8217;re in to its way of doing things.</li>
<li>The Rails results <del datetime="2010-11-19T08:35:10+00:00">left me a little confused</del> are interesting because Rails 2 apparently outperforms Rails 3 on Ruby 1.8. Of course, once you move to Ruby 1.9, Rails 3 runs quite nicely.</li>
<li>Don&#8217;t believe these numbers? Feel free to boot up your own EC2 instance and run one of the test apps:
<ul>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/pyramid.zip">Pyramid 1.0a3 test app code</a></li>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/django.zip">Django 1.2 test app code</a></li>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/tg21.zip">TurboGears 2.1 test app code</a></li>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/rails3.zip">Rails 3 test app code</a></li>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2010/11/rails2.zip">Rails 2 test app code</a></li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<p><strong>(Please don&#8217;t leave benchmarking requests as comments. If you&#8217;d like me to take a look at your favorite framework, direct message me on twitter. Thanks!)</strong></p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2010/11/the-great-web-technology-shootout-%e2%80%93-round-4-pyramid-vs-django-vs-tg-vs-rails-2-3/' addthis:title='The great web technology shootout – Round 4: Pyramid vs Django vs TG vs Rails 2 &amp; 3 ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2010/11/the-great-web-technology-shootout-%e2%80%93-round-4-pyramid-vs-django-vs-tg-vs-rails-2-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Facts, FUD and Fanboys: Why I&#8217;ve chosen Android over the iPhone</title>
		<link>http://blog.curiasolutions.com/2010/09/android-the-iphone-facts-vs-fud/</link>
		<comments>http://blog.curiasolutions.com/2010/09/android-the-iphone-facts-vs-fud/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 22:39:15 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=766</guid>
		<description><![CDATA[I&#8217;m not sure if anyone else&#8217;s world is like mine, but I work, eat, sleep, and breathe in a culture where Apple is king and the iPhone is the only phone. While I love Apple&#8217;s computers as much as the next guy (I always suggest that friends buy a Mac), I just don&#8217;t understand everyone&#8217;s [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2010/09/android-the-iphone-facts-vs-fud/' addthis:title='Facts, FUD and Fanboys: Why I&#8217;ve chosen Android over the iPhone ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not sure if anyone else&#8217;s world is like mine, but I work, eat, sleep, and breathe in a culture where Apple is king and the iPhone is <em>the only</em> phone. While I love Apple&#8217;s <em>computers</em> as much as the next guy (I always suggest that friends buy a Mac), I just don&#8217;t understand everyone&#8217;s extraordinary love affair with the iPhone. Sure, it&#8217;s awfully nice to look at and it has definitely raised the bar for what it means to be a mobile device, but at the end of the day your device is only as valuable as the enhanced productivity it is capable of providing. If there are issues or limitations to a device&#8217;s ability to enhance productivity, wouldn&#8217;t you be wary of such a device?</p>
<p>Well, I am the black sheep in my culture because I have an Android phone. This sometimes causes a bit of a stir with co-workers and friends (all in good fun though, right?), but every now and then I come across someone who is thinking about upgrading phones and wants to know why I&#8217;ve chosen Android over the iPhone. The answer is actually quite simple in my mind, and basically comes down to what I would consider the three &#8220;killjoy&#8221; facts about the iPhone:</p>
<p><span id="more-766"></span></p>
<blockquote><p>Fact #1: The iPhone is part of a &#8220;closed ecosystem&#8221;</p></blockquote>
<p>Non-techies will probably see the phrase &#8220;closed ecosystem&#8221; and dismiss it as tech jargon and quickly move on to the next point; but in my mind this is probably the most important issue of them all, and it actually has a much larger affect on the end-user than most people realize. (I won&#8217;t even start about how this affects the developers. That could be a whole blog post of its own!)</p>
<p>So, what exactly do I mean by a &#8220;closed ecosystem&#8221; and how does it affect the end-user? In my opinion, this is best described in an over-simplified and somewhat silly little story:</p>
<blockquote><p>Bob decides one day to go and buy a ~$500 ultra-mobile computing device from Steve. Bob loves how sleek and sexy his new device is, but whenever Bob wants to install a new program on his new device, Bob has to check-in with Steve and make sure Steve is okay with Bob installing that program. Bob isn&#8217;t given the option to install whatever he wants whenever he wants—he always has to go through whatever process has been set up to gain Steve&#8217;s approval in order to install anything.</p></blockquote>
<p>That sounds kind of silly doesn&#8217;t it? We typically expect to have the freedom to do anything we like with something we&#8217;ve bought for ourselves; and yet, this is exactly how the iPhone&#8217;s integration with the Apple App Store works. While most people might laugh at the idea of this being much of an issue (the App Store certainly doesn&#8217;t <em>feel</em> very restrictive to the uninformed), it actually <em>is</em> a <a href="http://www.saurik.com/id/12" target="_blank">pretty big deal to some people</a>, and it&#8217;s why the word &#8220;<a href="http://en.wikipedia.org/wiki/IOS_jailbreaking" target="_blank">jailbreak</a>&#8221; has become a household word for many Apple extremists.</p>
<p>So, how does this play out in the real world for the end-user? Well, to be fair, let me first highlight the fact that there can be some &#8220;pluses&#8221; (depending on how you look at it) to a more restrictive system. For one, Steve can make sure Bob never installs a &#8220;bad&#8221; program on his device (of course, Steve decides what &#8220;bad&#8221; means). Also, by acting as the sole party in charge of &#8220;authorizing&#8221; applications (and therefore the gateway-*cough*-bottleneck between the app developers and their customers), Steve can create all kinds of developer requirements based on what&#8217;s important to him (aesthetics, functionality, etc), thus raising the bar of what <em>kind</em> of apps are created for his device. (Of course, this also causes <a href="http://techcrunch.com/2009/11/11/joe-hewitt-developer-of-facebooks-massively-popular-iphone-app-quits-the-project/" target="_blank">headache</a> after <a href="http://www.businessinsider.com/adidas-gives-up-on-apples-iads-because-steve-jobs-is-too-much-of-a-control-freak-scuttlebutt-2010-10" target="_blank">headache</a> for the developers; but I promised I wouldn&#8217;t get into that here&#8230;)</p>
<p>That sounds nice right—but what happens if your good ol&#8217; buddy Steve decides he doesn&#8217;t like a certain program anymore, even if it is widely used and <a href="http://www.adobe.com/products/player_census/flashplayer/" target="_blank">supported by 99% of the market</a>? I&#8217;m sure you iPhone users reading this have encountered <a href="http://www.walyou.com/blog/2010/04/15/no-flash-support-iphone-ipad/" target="_blank">this fun little image</a> before. Yeah, Steve decided that Flash was &#8220;not cool&#8221; and has therefore decreed that it will forever be banned from iOS devices. Or how about something a little more offbeat? Wouldn&#8217;t you love to have <a href="http://www.youtube.com/watch?v=pLOrr_-twwA" target="_blank">this awesome little text-input app</a> on your iPhone? Well, sorry guys, applications that ask for that much core integration with the OS aren&#8217;t cool either according to Steve, so tough luck! In fact, Steve won&#8217;t even give you <a href="http://www.youtube.com/watch?v=dBQFXRW5ZiE#t=04m26s" target="_blank">tethering</a>! Now where&#8217;s the fun in that (especially if you travel as much as I do)? Sure, farts are cool. And birds hitting pigs? Yeah, that&#8217;s cool too. But at the end of the day, Steve has the final say. Not you.</p>
<p>Remember: You paid to use your iPhone how <em>Steve</em> wants you to use it, not necessarily how <em>you</em> want to use it.</p>
<blockquote><p>Fact #2: The iPhones (yes, even the 3GS!) really do have reception issues</p></blockquote>
<p>While I agree with the Apple fanboys that &#8220;antennagate&#8221; was blown <em>way</em> out of proportion, I would still argue that as a <em>phone</em>, the iPhone sucks. Most people have been too busy blaming AT&amp;T (see my next point) to accept the truth, but the fact of the matter is that studies have shown that the iPhone <a href="http://www.pcworld.com/article/203914/iphone_great_device_lousy_telephone.html" target="_blank">has poorer reception than other leading AT&amp;T phones</a>. Yes, you read that right—AT&amp;T might not have as much to do with your dropped calls as you may think.</p>
<p>And how about that &#8220;revolutionary new antenna design&#8221; in the iPhone 4 that Mr. Jobs kept going on about? Well, do you remember <a href="http://www.engadget.com/2010/07/16/apple-iphone-4-drops-less-than-one-additional-call-per-100-tha/" target="_blank">this slide</a> from the epic &#8220;antennagate&#8221; emergency press meeting? According to &#8220;call drop data from AT&amp;T&#8221; the iPhone 4 actually drops <em>more</em> calls than the 3GS. Oops!</p>
<blockquote><p>Fact #3: AT&amp;T has some serious issues with its network in many areas</p></blockquote>
<p>It&#8217;s no secret that AT&amp;T&#8217;s network has issues. Over the past 10 years I&#8217;ve had contracts with all four major carriers and AT&amp;T was definitely the worst in terms of call reliability. After switching back to a carrier other than AT&amp;T, I think I&#8217;ve only had <em>one</em> dropped call so far <em>this entire year</em> (as opposed to what sometimes felt like every other call on AT&amp;T). What a novel idea: having a complete conversation without ever having to hit redial!</p>
<p>But I don&#8217;t even live in a major metropolitan area where AT&amp;T&#8217;s network is over-saturated. Did you know that <a href="http://arstechnica.com/apple/news/2009/09/poll-technica-iphone-dropped-callsis-30-normal-defesible.ars" target="_blank">the <em>average</em> dropped call rate for NYC is 30%</a> (according to a September 2009 report)? I would find that absolutely unacceptable.</p>
<p>Oh, and don&#8217;t keep holding your breath, the iPhone <a href="http://tech.fortune.cnn.com/2010/09/23/ceo-ivan-seidenberg-pours-cold-water-on-verizon-iphone-rumor/" target="_blank">still doesn&#8217;t seem to be coming to Verizon</a> anytime soon.</p>
<blockquote><p>But, isn&#8217;t Android susceptible to these issues as well?</p></blockquote>
<p>Without going into too much detail, the answer is both &#8220;no&#8221; and &#8220;maybe.&#8221;</p>
<p>The biggest difference is the ecosystem. Since Android is deeply rooted in <a href="http://en.wikipedia.org/wiki/Open_source" target="_blank">open source</a>, both the developers and the end-users are given an incredible amount of freedom to do whatever they want with their devices. This freedom has spawned a thriving &#8220;aftermarket&#8221; community that has gifted us with such marvels as <a href="http://en.wikipedia.org/wiki/CyanogenMod" target="_blank">custom ROMs</a>, <a href="http://www.appbrain.com/" target="_blank">3rd party app stores</a>, and all combinations of <a href="http://code.google.com/p/adw-launcher-android/" target="_blank">tweaks</a>, <a href="http://www.engadget.com/2010/09/29/confirmed-droid-2-hack-brings-fm-radio-in-one-ear-and-out-the/" target="_blank">tricks</a> and <a href="http://lifehacker.com/5653345/install-a-front+facing-camera-on-a-samsung-galaxy-s" target="_blank">enhancements</a>. But have no fear—if you&#8217;re someone who doesn&#8217;t like to get his or her feet wet pushing the bounds of your freedom, Google still has you covered with its own app store for an &#8220;official&#8221; application install channel.</p>
<p>Of course, any phone can have antenna issues (something Mr. Jobs has been clear to point out), so it would be nice to see data on dropped calls for a comparable Android phone on AT&amp;T&#8217;s network. However, the nice thing about the fact that Android is an <em>operating system</em> and not a phone (remember: the <em>Droid</em> is a phone and <em>Android</em> is the operating system that it and many other Android phones run) is that there are Android devices available on pretty much *every* mobile carrier of any size <a href="http://www.google.com/phone/" target="_blank">in the US</a> and all over the world.</p>
<blockquote><p>But the iPhone 4 still blows Android out of the water feature and spec wise, right?</p></blockquote>
<p>Actually, no. There are Android phones out there with more memory and processing power, higher resolution cameras (on the front and back), better battery life, and more vibrant displays (although &#8220;Retina&#8221; vs SuperAMOLED is probably still a personal preference thing).</p>
<p>Okay, I know what you&#8217;re thinking now: &#8220;What about FaceTime?&#8221; Well, the truth is that Android was doing face-to-face mobile video calls <em>before the iPhone 4 was even announced</em>. Crazy right? Well, here&#8217;s something else Apple probably doesn&#8217;t want you to know: Not only can you use an Android device to have FaceTime-like video chats with both iPhone 4 users and other Android users, but you also aren&#8217;t restricted to WiFi-only usage!</p>
<p>Oh, and remember: &#8220;successfully placing calls&#8221; should probably be pretty high up on your feature-list for a smart<em>phone</em>.</p>
<blockquote><p>&#8220;I Don&#8217;t Care! I Want An iPhone 4!&#8221;</p></blockquote>
<p>At the end of the day though, most people approach choosing a phone in much the same way as if they were choosing a watch or a new pair of sunglasses—it&#8217;s all about what looks good to them. The iPhone has an aura about it that is beautiful and sexy; and evidentially many people either do all of their phone talking within excellent AT&amp;T coverage areas (somewhere out there I&#8217;m sure such a thing exists), or they really don’t mind having calls drop on them. After all, you can always just hit redial, right? The overwhelming response by most iPhone fans to the issues I&#8217;ve raised above is either denial, or an emphatic &#8221;<a href="http://www.youtube.com/watch?v=FL7yD-0pqZg" target="_blank">I Don&#8217;t Care</a>&#8221; (warning: lots of NSFW language in that hilarious youtube video).</p>
<p>And why should they care? After all, <a href="http://www.wired.com/gadgetlab/2010/08/gadget-sex/" target="_blank">they have an iPhone</a>!</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2010/09/android-the-iphone-facts-vs-fud/' addthis:title='Facts, FUD and Fanboys: Why I&#8217;ve chosen Android over the iPhone ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2010/09/android-the-iphone-facts-vs-fud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The great web technology shootout &#8211; Round 3: Better, Faster, and Shinier</title>
		<link>http://blog.curiasolutions.com/2009/10/the-great-web-technology-shootout-round-3-better-faster-and-shinier/</link>
		<comments>http://blog.curiasolutions.com/2009/10/the-great-web-technology-shootout-round-3-better-faster-and-shinier/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 18:42:52 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=409</guid>
		<description><![CDATA[[A lot of the information below is out of date. Please see the new framework shootout page for the latest benchmarks.] [Note: This post is the continuation of a series. Please read Round 1 and Round 2 first if you are just now joining us.] As I briefly mentioned in Round 1, this whole thing [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/10/the-great-web-technology-shootout-round-3-better-faster-and-shinier/' addthis:title='The great web technology shootout &#8211; Round 3: Better, Faster, and Shinier ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><strong>[A lot of the information below is out of date. Please see the new <a href="http://blog.curiasolutions.com/?p=963">framework shootout page</a> for the latest benchmarks.]</strong></p>
<p>[Note: This post is the continuation of a series. Please read <a href="http://blog.curiasolutions.com/?p=172">Round 1</a> and <a href="http://blog.curiasolutions.com/?p=278">Round 2</a> first if you are just now joining us.]</p>
<p>As I briefly mentioned in <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>, this whole thing came about as an experiment to satisfy my own curiosity. Unfortunately, I wasn&#8217;t expecting these posts to draw the amount of attention they have been getting, and several people informed me of a few &#8220;issues&#8221; with the first round. Since my initial approach to this topic was somewhat casual, I didn&#8217;t really take the time to perform each test in a &#8220;proper scientific fashion.&#8221; Although this was clearly stated in the introduction to round one, it unfortunately resulted in performance estimations that were somewhat less than accurate.</p>
<p>After input from various people much smarter than myself, I quickly went to work tweaking my test environment and building &#8220;proper&#8221; test apps. In the midst of this, a conversation about PHP accelerators prompted me to put PHP under the spotlight, which brought about <a href="http://blog.curiasolutions.com/?p=278">Round 2</a> as an interim round. This gave me a chance to demonstrate the necessity of PHP acceleration, and only continued to solidify my opinion of PHP as an inferior web development language (remember, I just said <em>my opinion</em>).</p>
<p>Which brings us to Round 3. A lot of work has gone into &#8220;doing it right&#8221; this time, so I am fairly confident that these results are a much more accurate representation of each test subject&#8217;s performance estimations. Remember, benchmark test code typically has no real-world value, so &#8220;performance estimations&#8221; are about all I can promise here. <strong>Your mileage <em>will</em> vary.</strong> As a wise person once said:</p>
<blockquote><p>&#8220;All this benchmarking is doing is proving what we already know: More code takes longer to execute.&#8221; &#8211; Ben Bangert (dev lead of Pylons)</p></blockquote>
<p><span id="more-409"></span></p>
<p>&nbsp;</p>
<p>What you should know about Round 3:</p>
<ul>
<li>The hardware/software platform is the same as in <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>.</li>
<li>Python v2.5.4 was used for all the Python tests. Ruby v1.8.6 was used for the Rails test.</li>
<li>Apache v2.2.3 was used, with <a href="http://code.google.com/p/modwsgi/" target="_blank">mod_wsgi</a> v2.5 for the Python tests and <a href="http://www.modrails.com/" target="_blank">Phusion Passenger</a> v2.2.5 for the Rails test.</li>
<li>Note that while the mod_wsgi tests in Round 1 were using &#8220;daemon mode&#8221;, the mod_wsgi tests here are using &#8220;embedded mode&#8221; which is often faster (although <a href="http://blog.dscpl.com.au/2009/03/load-spikes-and-excessive-memory-usage.html" target="_blank">not necessarily the recommended configuration)</a>.
<li>The Python component versions used here were: SQLAlchemy v0.5.6, Genshi v0.5.1, Mako v0.2.5, and Jinja 2.2.1.</li>
<li>ApacheBench was run with -n 10000 -c 10.</li>
<li>Each test was run several times to make sure that there were no anomalies, with the &#8220;optimum average&#8221; chosen as the numbers represented here.</li>
<li>In an attempt to try to make these tests more scientific, I am now including the source code for each test.</li>
</ul>
<p>&nbsp;</p>
<blockquote><h4>Plain WSGI – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/wsgi_test_src.zip">wsgi_test_src.zip</a></h4>
</blockquote>
<p>Let&#8217;s start with a basic &#8220;hello world&#8221; WSGI test to set the baseline:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">WSGIServer</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">0.1</span>
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1532.76</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Apache<span style="color: #66cc66;">/</span>2<span style="color: #66cc66;">.</span>2<span style="color: #66cc66;">.</span>3 <span style="color: #66cc66;">&#40;</span>mod_wsgi<span style="color: #66cc66;">&#41;</span>
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">5549.73</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, mod_wsgi allows Apache to put some serious muscle into Python&#8217;s WSGI. It&#8217;s no wonder that mod_wsgi is quickly becoming the de-facto standard for Apache Python deployment.</p>
<p>&nbsp;</p>
<blockquote><h4>TurboGears v2.0.3 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/tg2_test_src.zip">tg2_test_src.zip</a></h4>
</blockquote>
<p>As I mentioned in Round 1, <a href="http://www.turbogears.org/" target="_blank">TurboGears</a> has quickly become my web framework of choice. Building a &#8220;best-of-breed&#8221; component stack on top of Pylons <a href="http://percious.com/blog/?p=31" target="_blank">may not be easy</a>, but <a href="http://percious.com/blog/?p=32" target="_blank">when it works</a> I believe it pays off immensely (e.g. Ubuntu).</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">935.13</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Genshi template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>genshi_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">923</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">601.07</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Mako template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>mako_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">932</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">723.18</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Jinja2 template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>jinja_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">937</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">764.35</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> tests<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>raw_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1270</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">569.71</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>genshi_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2409</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">388.96</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>mako_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2418</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">515.07</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>jinja_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2472</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">535.06</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&nbsp;</p>
<blockquote><h4>TurboGears v2.1a1 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/tg21_test_src.zip">tg21_test_src.zip</a></h4>
</blockquote>
<p>The TurboGears community is alive and well, and just before finishing this post the release of v2.1 Alpha 1 was announced. Significant improvements were made to TG&#8217;s object dispatch, so I was excited to see what the new numbers would look like.</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">11</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1118.92</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Genshi template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>genshi_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">923</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">713.97</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Mako template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>mako_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">932</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">812.64</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Jinja2 template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>jinja_hello<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">937</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1000.98</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> tests<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>raw_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1270</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">673.04</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>genshi_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2409</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">433.45</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>mako_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2418</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">601.89</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>jinja_sql<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2472</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">630.66</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, the future of TurboGears looks very bright, and I only expect these numbers to get better as the final 2.1 release approaches (expected in Q1 2010).</p>
<p>&nbsp;</p>
<blockquote><h4>Pylons v0.9.7 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/pylons_test_src.zip">pylons_test_src.zip</a></h4>
</blockquote>
<p><a href="http://www.pylonshq.com/" target="_blank">Pylons</a> is the foundation which TurboGears is built upon, and for those who don&#8217;t need all &#8220;the extras&#8221; it is an excellent choice.</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">2593.47</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Mako template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">932</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1737.03</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> tests<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>raw_sql
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1270</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">964.07</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>hellodb
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2418</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">831.26</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&nbsp;</p>
<blockquote><h4>Django v1.1 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/django_test_src.zip">django_test_src.zip</a></h4>
</blockquote>
<p>While <a href="http://www.djangoproject.com/" target="_blank">Django</a> is probably Python&#8217;s most popular web framework, I have never really clicked with it. Its way of doing things is significantly different than TG/Pylons, but if you don&#8217;t mind its &#8220;<a href="http://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names" target="_blank">MTV</a>&#8221; architectural pattern and can survive without SQLAlchemy (although there are hacks), it is a very capable framework.</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3376.48</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Django template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">936</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1781.43</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellodb
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2476</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">972.11</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&nbsp;</p>
<blockquote><h4>Bottle 0.5.8 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/bottle_test_src.zip">bottle_test_src.zip</a></h4>
</blockquote>
<p><a href="http://bottle.paws.de/" target="_blank">Bottle</a> caught my attention a few months ago while surveying the WSGI landscape for an alternative to PHP when building websites that only require a few pieces of dynamic functionality. As a &#8220;micro-framework&#8221;, it does an excellent job at bridging the gap between &#8220;pure WSGI&#8221; and its &#8220;feature-rich&#8221; big brothers.</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">5545.96</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Mako template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">923</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3588.04</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span>SQLAlchemy<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellodb
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2413</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1479.54</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, there was practically no difference in speed between Bottle and pure WSGI in a basic &#8220;hello world&#8221; test. Even with the addition of Mako and SQLAlchemy, Bottle performed significantly faster than a bare Pylons or Django setup.</p>
<p>(Note: Mako template inheritance was not used in the Bottle Mako test.)</p>
<p>&nbsp;</p>
<blockquote><h4>Ruby on Rails v2.3.3 – <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/rails_test_src.zip">rails_test_src.zip</a></h4>
</blockquote>
<p>What web technology shootout would be complete without <a href="http://www.rubyonrails.org/" target="_blank">Rails</a>? Although I am not a Rails fan (mostly because I can&#8217;t stand Ruby), I believe that in many ways we owe much of the popularity and success of the web framework movement to Rails.</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1048.18</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Rails template test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>hellos
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">937</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">949.54</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
Database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span>hellodb
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2482</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">734.18</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>(Note: I think my version of Ruby was using a newer version of the SQLite3 library than my version of Python. This may or may not have given Rails an advantage on the database query test.)</p>
<p>&nbsp;</p>
<p>For those of you who like charts, here&#8217;s a comparison of the &#8220;return hello world&#8221; test results for each framework:</p>
<div id="attachment_531" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/hello_world_test.png"><img src="http://blog.curiasolutions.com/wp-content/uploads/2009/10/hello_world_test.png" alt="The return hello world test chart" title="Hello World Test" width="556" height="352" class="size-full wp-image-531" /></a><p class="wp-caption-text">The return hello world test chart</p></div>
<p>And here&#8217;s a comparison of the template test:</p>
<div id="attachment_532" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/template_test.png"><img src="http://blog.curiasolutions.com/wp-content/uploads/2009/10/template_test.png" alt="The template test chart" title="Template Test" width="556" height="263" class="size-full wp-image-532" /></a><p class="wp-caption-text">The template test chart</p></div>
<p>Finally, here&#8217;s the template test with the database query added:</p>
<div id="attachment_530" class="wp-caption aligncenter" style="width: 566px"><a href="http://blog.curiasolutions.com/wp-content/uploads/2009/10/database_test.png"><img src="http://blog.curiasolutions.com/wp-content/uploads/2009/10/database_test.png" alt="Template test with database query" title="Database Query" width="556" height="264" class="size-full wp-image-530" /></a><p class="wp-caption-text">Template test with database query</p></div>
<p>&nbsp;</p>
<h4>Closing thoughts</h4>
<ul>
<li>Gone are the days of Rails as &#8220;the one framework to rule them all.&#8221; C&#8217;mon guys, it&#8217;s not 2005 anymore.</li>
<li>Python has gotten a lot of flak from other language camps for its abundance of web frameworks. While some Pythonists have been embarrassed by this, I only see it as proof of Python&#8217;s success as a language. My retort would be: &#8220;If it was as easy to write a web framework in your language as it is in Python, you&#8217;d have the same problem!&#8221;</li>
</ul>
<p>&nbsp;</p>
<h5>Looking for updated results? Check out <a href="http://blog.curiasolutions.com/?p=915">Round 4</a>&#8230;</h5>
<p>(Note: Please don&#8217;t leave benchmarking requests as comments. If you&#8217;d like me to take a look at your favorite framework, direct message me on twitter. Thanks!)</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/10/the-great-web-technology-shootout-round-3-better-faster-and-shinier/' addthis:title='The great web technology shootout &#8211; Round 3: Better, Faster, and Shinier ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/10/the-great-web-technology-shootout-round-3-better-faster-and-shinier/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>The great web technology shootout &#8211; Round 2: PHP deserves a helping hand</title>
		<link>http://blog.curiasolutions.com/2009/09/the-great-web-technology-shootout-round-2-php-deserves-a-helping-hand/</link>
		<comments>http://blog.curiasolutions.com/2009/09/the-great-web-technology-shootout-round-2-php-deserves-a-helping-hand/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 06:53:41 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=278</guid>
		<description><![CDATA[[A lot of the information below is out of date. Please see the new framework shootout page for the latest benchmarks.] [This post is the continuation of a series. Please read Round 1 first if you are just now joining us.] In Round 1, PHP was looking like quite the tortoise of the group. However, [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/09/the-great-web-technology-shootout-round-2-php-deserves-a-helping-hand/' addthis:title='The great web technology shootout &#8211; Round 2: PHP deserves a helping hand ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><strong>[A lot of the information below is out of date. Please see the new <a href="http://blog.curiasolutions.com/?p=963">framework shootout page</a> for the latest benchmarks.]</strong></p>
<p>[This post is the continuation of a series. Please read <a href="http://blog.curiasolutions.com/?p=172">Round 1</a> first if you are just now joining us.]</p>
<p>In <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>, PHP was looking like quite the tortoise of the group. However, if you&#8217;re familiar with some of the core differences between Python &amp; PHP, you&#8217;ll know that Python has been &#8220;cheating&#8221; slightly.</p>
<p>Let me explain: By default, Python compiles each script into bytecode on its first execution, allowing this bottleneck to be skipped on subsequent runs. PHP, however does not perform this type of optimization by default (in the 5.x line at least), so the PHP interpreter must re-compile each file every time it is run. As you can imagine, this can give PHP (without an accelerator) a huge disadvantage when compared to languages such as Python.</p>
<p><strong>With this in mind, I have decided to take Round 2 to focus solely PHP.</strong> This will hopefully provide a clear picture of the benefits of PHP bytecode caching (at least when it comes to page-views — the memory benefits are a whole other story), and give you an idea of PHP&#8217;s performance with the help of an accelerator.</p>
<p>There are <a href="http://en.wikipedia.org/wiki/List_of_PHP_accelerators" target="_blank">many PHP accelerators available</a>, but I have chosen <a href="http://php.net/apc" target="_blank">APC</a> for use here (mostly due to its inclusion in the upcoming PHP 6 core).<span id="more-278"></span></p>
<h5>What you should know about Round 2:</h5>
<ol>
<li>The hardware/software platform is the same as in <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>.</li>
<li>PHP has been upgraded to v5.2.9.</li>
<li>The APC tests are using APC v3.0.19.</li>
<li>ApacheBench was run with -n # -c 10, with -n usually being 5000 or 10000, depending on the test subject&#8217;s speed.</li>
<li>Each test was run several times to make sure that there were no anomalies, with the &#8220;optimum average&#8221; chosen as the numbers represented here.</li>
<li>In an attempt to try to make these tests more scientific, I am now including the source code for each test (minus the CMS tests, which were performed on a standard install).</li>
</ol>
<p>My apc.ini settings:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000099;">extension</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> apc.so</span>
apc.enabled <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
apc.shm_size <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 96</span>
apc.include_once_override <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
apc.mmap_file_mask <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /tmp/apc.XXXXXX</span></pre></div></div>

<blockquote>
<h4>Raw PHP &#8211; <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/09/php_test_src.zip">php_test_src.zip</a></h4>
</blockquote>
<p>To investigate the speed of &#8220;raw PHP&#8221;, I created a couple of minimal PHP scripts that printed out a simple &#8220;hello world&#8221;, and read a few lines of text from a database. Take a look at the test source code for reference.</p>
<h5>APC Disabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">.</span>php
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">4199.43</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello_db<span style="color: #66cc66;">.</span>php
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2524</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">2797.54</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Enabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">.</span>php
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">6618.42</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello_db<span style="color: #66cc66;">.</span>php
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2524</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3713.99</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Right out of the gate, we can see that APC gives PHP a significant boost.</p>
<p>Of course, a script that simply does a &#8220;echo &#8216;hello world&#8217;&#8221; isn&#8217;t really practical, so let&#8217;s take a look at a couple of popular PHP frameworks to see what a full stack looks like.</p>
<blockquote>
<h4>CakePHP v1.2.5 &#8211; <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/09/cakephp_test_src.zip">cakephp_test_src.zip</a></h4>
</blockquote>
<p>CakePHP was the slowest test subject by a large margin in <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>, but if you take a look at the caching section of its core configuration file you can see that the developers have written it with acceleration in mind. It includes special configuration directives for not just APC, but also <a href="http://xcache.lighttpd.net/" target="_blank">Xcache</a> and <a href="http://www.danga.com/memcached/" target="_blank">Memcache</a>.</p>
<p>Still though, without acceleration CakePHP is a sad story indeed:</p>
<h5>APC Disabled &#8211; File Caching Engine (default)</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">13</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">45.25</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The template hello world test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">931</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">39.90</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the ORM<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>hello_db
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2469</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">38.80</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>However, with the help of APC things finally begin to look reasonable:</p>
<h5>APC Enabled &#8211; APC Caching Engine (in core.php)</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">13</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">140.98</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The template hello world test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>hello
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">931</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">120.04</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the ORM<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span>hello_db
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2469</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">117.56</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, APC increases CakePHP&#8217;s speed about threefold in these examples. These results may or may not be acceptable to you (remember that we are running these tests with a concurrency of 10), but I felt much better about CakePHP after pairing it with APC.</p>
<blockquote>
<h4>Kohana v3.0 &#8211; <a href="http://blog.curiasolutions.com/wp-content/uploads/2009/09/kohana3_test_src.zip">kohana3_test_src.zip</a></h4>
</blockquote>
<p>Kohana (a divergent of CodeIgnitor) is a much more lightweight PHP framework than CakePHP, but still gives you a pretty full featureset. Since v3.0 was released shortly after <a href="http://blog.curiasolutions.com/?p=172">Round 1</a>, I decided to use the new version for the tests here in Round 2.</p>
<p>It should be noted that although file caching is enabled in a default CakePHP install, Kohana&#8217;s caching is disabled by default. I have included a couple of tests with caching disabled here to exhibit the performance of a default Kohana install.</p>
<h5>APC Disabled &#8211; Caching Disabled (default)</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">86.73</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Disabled &#8211; Caching Enabled (bootstrap.php)</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">180.50</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The template hello world test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">930</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">162.27</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the Database module<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellodb<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2525</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">113.92</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the ORM module<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>helloorm<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2525</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">99.73</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, even without APC Kohana is quite a bit faster than CakePHP.</p>
<h5>APC Enabled &#8211; Caching Disabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">125.93</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Enabled &#8211; Caching Enabled (bootstrap.php)</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">The <span style="color: #993333;">RETURN</span> <span style="color: #ff0000;">'hello world'</span> test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hello<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">280.67</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The template hello world test<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellos<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">930</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">253.50</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the Database module<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>hellodb<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2525</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">173.28</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
The simple database <span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">QUERY</span> test <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff; font-weight: <span style="color: #006600;">bold</span>;">USING</span> the ORM module<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>helloorm<span style="color: #66cc66;">/</span><span style="color: #993333;">INDEX</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">2525</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">153.90</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Although not a threefold gain as with CakePHP, Kohana with APC+caching definitely makes a good attempt at shortening the gap seen in <a href="http://blog.curiasolutions.com/?p=172">Round 1</a> between the PHP frameworks and the offerings from other languages. Of course, if raw speed is what you&#8217;re looking for, there are <a href="http://www.doophp.com/benchmark" target="_blank">faster PHP frameworks available</a> (note that the benchmarks on that page were run on a completely different setup and should not be compared with any of the numbers here).</p>
<p><strong>Next, let&#8217;s take a look at how APC enhances the performance of a few of PHP&#8217;s heavyweights.</strong></p>
<blockquote>
<h4>WordPress v2.8.4 (default install)</h4>
</blockquote>
<p>Although I&#8217;ve heard that WordPress has a built-in caching setting, a quick glance at wp-settings.php did not reveal anything. So, there are simply two WordPress tests—with APC, and without:</p>
<h5>APC Disabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5519</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">24.80</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Enabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5519</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">74.00</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<blockquote>
<h4>Joomla v1.5.14 (default install, without sample data)</h4>
</blockquote>
<p>The results of these tests were quite disappointing to me, and made me wonder if I was doing something wrong. Sadly, it looks as though Joomla is quite the slow one of the bunch.</p>
<h5>APC Disabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Joomla Caching Disabled <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">DEFAULT</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">4006</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">27.90</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Joomla Caching Enabled <span style="color: #66cc66;">&#40;</span>File<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">4006</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">31.46</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Enabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Joomla Caching Disabled<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">4006</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">41.27</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
Joomla Caching Enabled <span style="color: #66cc66;">&#40;</span>APC<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">4006</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">45.01</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<blockquote>
<h4>Drupal v6.14 (default install, clean URLs disabled)</h4>
</blockquote>
<p>Drupal has several caching settings, so I decided to see what each one would look like and how much of a difference &#8220;aggressive&#8221; caching made.</p>
<h5>APC Disabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Drupal Caching Disabled <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">DEFAULT</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">36.72</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #ff0000;">&quot;Normal&quot;</span> Drupal Caching<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">289.69</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #ff0000;">&quot;Aggressive&quot;</span> Drupal Caching<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">335.68</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h5>APC Enabled</h5>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Drupal Caching Disabled<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">83.93</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #ff0000;">&quot;Normal&quot;</span> Drupal Caching<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">498.37</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #ff0000;">&quot;Aggressive&quot;</span> Drupal Caching<span style="color: #66cc66;">:</span>
&nbsp;
<span style="color: #006600;">Document</span> Path<span style="color: #66cc66;">:</span>          <span style="color: #66cc66;">/</span>
Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">5548</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">564.48</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, Drupal&#8217;s caching (especially when combined with APC) changes things drastically. These results seem to indicate that Drupal&#8217;s caching does a great job of allowing the CMS to get out of the way.</p>
<h4>Closing thoughts</h4>
<ul>
<li>The benefits of a PHP accelerator are really too good to pass up. Even without written-in caching, an accelerator can give your code a significant boost.</li>
<li>While these tests have only really explored the impact on website page-load times, a PHP accelerator typically also cuts down on the amount of memory used by your PHP scripts.</li>
<li>PHP 6 has promised to fix a lot of things, including the lack of built-in bytecode caching. It will be interesting to revisit these tests in a few years (?) to see how much optimization the new version brings to the table.</li>
</ul>
<h5>Can&#8217;t get enough of this madness? Just wait until you read <a href="http://blog.curiasolutions.com/?p=409">Round 3</a>!</h5>
<p>(Note: Please don&#8217;t leave benchmarking requests as comments. If you&#8217;d like me to take a look at your favorite framework, direct message me on twitter. Thanks!)</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/09/the-great-web-technology-shootout-round-2-php-deserves-a-helping-hand/' addthis:title='The great web technology shootout &#8211; Round 2: PHP deserves a helping hand ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/09/the-great-web-technology-shootout-round-2-php-deserves-a-helping-hand/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The great web technology shootout &#8211; Round 1: A quick glance at the landscape</title>
		<link>http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/</link>
		<comments>http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 05:29:28 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=172</guid>
		<description><![CDATA[[A lot of the information below is out of date. Please see the new framework shootout page for the latest benchmarks.] Recently I went on a benchmarking spree and decided to throw ApacheBench at a bunch of the different web development technology platforms I interact with on a day-to-day basis. The results were interesting enough [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/' addthis:title='The great web technology shootout &#8211; Round 1: A quick glance at the landscape ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><strong>[A lot of the information below is out of date. Please see the new <a href="http://blog.curiasolutions.com/?p=963">framework shootout page</a> for the latest benchmarks.]</strong></p>
<p>Recently I went on a benchmarking spree and decided to throw <a href="http://en.wikipedia.org/wiki/ApacheBench" target="_blank">ApacheBench</a> at a bunch of the different web development technology platforms I interact with on a day-to-day basis. The results were interesting enough to me that I decided I&#8217;d take a post to share them here.</p>
<p><strong>Disclaimer: The following test results should be taken with a <em>massive</em> grain of salt.</strong> If you know anything about benchmarking, you will know that the slightest adjustments have the potential to change things drastically. While I have tried to perform each test as fairly and accurately as possible, it would be foolish to consider these results as scientific in any way. <strong>It should also be noted that my goal here was not to see how fast each technology performs at its most optimized configuration, but rather what a minimal out-of-the-box experience looks like.</strong></p>
<p>Test platform info:</p>
<ul>
<li>The hardware was an Intel Core2Quad Q9300, 2.5Ghz, 6MB Cache, 1333FSB, 2GB DDR RAM.</li>
<li>The OS was CentOS v5.3 32-bit with a standard Apache Webserver setup.</li>
<li> ApacheBench was used with only the -n and -c flags (1000 requests for the PHP frameworks, 5000 requests for everything else).	</li>
<li> Each ApacheBench test was run 5-10 times, with the &#8220;optimum average&#8221; chosen as the numbers represented here.</li>
<li>The PHP tests were done using the standard Apache PHP module.</li>
<li>The mod_wsgi tests were done in daemon mode set to 2 processes/15 threads.</li>
<li>The SQL tests were done with mysqli ($mysql->query()) on PHP, and SQLAlchemy (conn.execute()) on Python fetching and printing 5 rows of data from a sample database.</li>
</ul>
<p>&nbsp;</p>
<h4>Apache v2.2.3</h4>
<p>We will start with the raw Apache benchmark.</p>
<p>For this test, Apache loaded a simple HTML file with random text:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">6537</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">8356.23</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As expected, Apache is lightning fast.</p>
<p>Ok, so now that we&#8217;ve set the high water mark, let&#8217;s take a look at some popular web technology platforms&#8230;<span id="more-172"></span></p>
<p>&nbsp;</p>
<h4>PHP v5.2.8</h4>
<p>For this test, I created a PHP file that simply printed the $_SERVER array and some random text:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">6135</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">2812.22</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Next, I decided to add some mysqli() code to connect to a database and print out a few rows of data:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">283</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">2135.46</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Not at all bad, but who really wants to build a webapp using plain old PHP anymore?</p>
<p>Next I decided to test the two PHP frameworks that I am most familiar with.</p>
<p>&nbsp;</p>
<h4>CakePHP v1.2.5</h4>
<p>For this test, I did a basic CakePHP install, and added a route that printed &#8220;hello world&#8221; from a template:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">944</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">42.00</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, frameworks can be a blessing and a curse. On a side note, CakePHP was the only test that gave me failed requests.</p>
<h4>Kohana v2.3.4</h4>
<p>For this test, I did a basic install and loaded Kohana&#8217;s default welcome/index setup (which seemed lightweight enough to me to qualify as the test focal point):</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1987</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">100.11</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Kohana fared much better than CakePHP, but it appears as though PHP&#8217;s speed breaks down quickly once you start building a framework around it.</p>
<p>&nbsp;</p>
<h4>Python v2.5.4</h4>
<p>Unlike PHP, Python wasn&#8217;t specifically created for the web. However, several years ago the <a href="http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface" target="_blank">WSGI spec</a> was introduced which makes building web applications with Python a breeze. There are many different ways to depoly a WSGI app, but my tests were limited to Python&#8217;s built-in WSGIServer, and Apache&#8217;s <a href="http://code.google.com/p/modwsgi/" target="_blank">mod_wsgi</a>.</p>
<h4>WSGIServer</h4>
<p>For this test, I used WSGI.org&#8217;s <a href="http://hg.moinmo.in/moin/1.8/raw-file/tip/wiki/server/test.wsgi" target="_blank">test.wsgi</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">4123</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1658.35</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>These results were quite impressive to me, considering that this is pure Python at work.</p>
<h4>mod_wsgi</h4>
<p>mod_wsgi is Apache&#8217;s module to process WSGI scripts. This test used the exact same script as the previous WSGIServer example:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">9552</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3994.30</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Don&#8217;t look now, but those results are better than the vanilla PHP test!</p>
<p>Next, I added SQLAlchemy imports to the test file and did a conn.execute(), in an attempt to try to mimic the PHP mysqli() test:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">10212</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3379.87</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>I expected to lose quite a bit of speed with the introduction of an ORM, but it looks like SQLAlchemy is quite fast. These results were still over 1,000reqs/s more than the PHP example.</p>
<h4>TornadoServer</h4>
<p>There&#8217;s been a lot of buzz lately about the new <a href="http://www.tornadoweb.org/" target="_blank">TornadoServer</a>, so I thought I&#8217;d throw it in the mix. This test uses their basic &#8220;hello world&#8221; example:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3330.00</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Nothing shocking here at first glance, but the Tornado is built to handle extreme loads. So, I increased the concurrency to 1,000 and threw 10,000 requests at it:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Concurrency Level<span style="color: #66cc66;">:</span>      <span style="color: #cc66cc;">1000</span>
<span style="color: #0000ff;">COMPLETE</span> requests<span style="color: #66cc66;">:</span>      <span style="color: #cc66cc;">10000</span>
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3288.15</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Almost exactly the same results! On a side note, none of the other tests subjects were able to handle a concurrency of 1,000.</p>
<p>&nbsp;</p>
<h4>TurboGears v2.0.3 (mod_wsgi)</h4>
<p><a href="http://www.turbogears.com/" target="_blank">TurboGears</a> has quickly become my framework of choice, so naturally it was the first Python framework I tested.</p>
<p>For this test I setup a default quickstart project, and then added a hello() controller method which simply returned a &#8220;hello world&#8221; string:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">11</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">470.18</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Next, I added a simple Genshi template with 1 level of inheritance:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1351</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">143.26</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>While those results are not terrible, they should encourage you to check out the other templating options.</p>
<p>Next, I performed the same test with Mako:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1534</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">394.41</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, Mako is significantly faster than Genshi.</p>
<p>TurboGears also supports Jinja2, so I thought I&#8217;d also see how it held up:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1020</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">401.04</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>I was not expecting Jinja2 to be faster than Mako, so I am not entirely sure about these results. However, the difference is only slight, and might have something to do with the fact that the dotted template names finder is disabled for Jinja templates.</p>
<h4>Pylons v0.9.7 (mod_wsgi)</h4>
<p>Mark Ramm (the current development lead of TurboGears) has been quoted as saying &#8220;TurboGears is to Pylons as Ubuntu is to Debian.&#8221; With that in mind, I naturally wanted to see how much speed I was losing with TurboGears&#8217; &#8220;additions&#8221;.</p>
<p>For this test I tried to mimic the first TurboGears test (basic layout, returning a string):</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">11</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1961.00</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>While I was expecting a gain from TurboGears&#8217; omissions, I wasn&#8217;t quite expecting over four times the increase. I can only assume that the bare Pylons setup is pretty minimal, while TurboGears bootstraps a lot of stuff on for you by default.</p>
<p>Duplicating the Mako test in Pylons was also quite fast:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">9743</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">1183.39</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h4>Bottle v0.5.7 (mod_wsgi)</h4>
<p><a href="http://bottle.paws.de/" target="_blank">Bottle</a> caught my attention recently as a minimalistic Python web framework, so I thought I&#8217;d put it through the grind as well.</p>
<p>For this test, I used their simple &#8220;hello world&#8221; example:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">12</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3912.43</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As you can see, Bottle is very close to bare WSGI as far as speed goes. On a side note, adding a sample template using Bottle&#8217;s default templating package didn&#8217;t seem to change these numbers at all.</p>
<p>Next I tested Bottle with its templating system switched to Mako:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">41</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">3134.61</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Then I added a SQLAlchemy and performed a query:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">9374</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">2503.27</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>What was exciting to me about this test was that I found myself looking at a minimal Python framework equipped with a full templating system and ORM which all performed faster than the PHP+mysqli() test.</p>
<h4>Django v1.1 (mod_wsgi)</h4>
<p>I don&#8217;t use <a href="http://www.djangoproject.com/" target="_blank">Django</a>, but I thought it would be worth including in this report. This is a basic Django setup printing out a simple hello world template:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1471</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">564.41</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As expected, a minimal Django setup is quite fast. (Note: This test included a SQLite database query.)</p>
<p>&nbsp;</p>
<h4>Ruby On Rails v2.2.3 (mod_passenger)</h4>
<p>I also don&#8217;t use <a href="http://rubyonrails.org/" target="_blank">Rails</a>, but I figured this report would be incomplete without Rails on the list. So, I took <a href="http://gems.mediatemple.net/testapp_rails.tgz">MediaTemple&#8217;s Rails test app</a> and loaded up a test page:</p>

<div class="wp_syntax"><div class="code"><pre class="progress" style="font-family:monospace;">Document <span style="color: #993333;">LENGTH</span><span style="color: #66cc66;">:</span>        <span style="color: #cc66cc;">1291</span> bytes
Requests per second<span style="color: #66cc66;">:</span>    <span style="color: #cc66cc;">433.57</span> <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">/</span>sec<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>mean<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Note that the test app used here is doing a little bit more than just returning &#8220;Hello World&#8221;.</p>
<p>&nbsp;</p>
<h4>My Conclusions</h4>
<p>As I said in the disclaimer, to arrive at any sort of decisive conclusions based on these numbers alone would be foolish. However, here is what all of this left me thinking:</p>
<ul>
<li>All of these technologies performed adequately for use with most projects.</li>
<li>CakePHP was the only test that produced less than 100 requests per second. However, there are many articles available on optimizing CakePHP.</li>
<li>These results made me wish I had moved away from PHP much earlier in my web development carrier. There are just better options these days when it comes to choosing a web development language (imho). If you <em>must</em> use PHP for a large project, I strongly suggest that you look into <a href="http://en.wikipedia.org/wiki/PHP_accelerator" target="_blank">an accelerator</a>.</li>
<li>The Bottle+Mako+SQLAlchemy results struck me as an extremely minimal drop-in replacement for simple PHP sites.</li>
<li>mod_wsgi is a huge winner in deploying Python webapps. Way to go Graham!</li>
<li>Do your own bencharking, because <em>your mileage <strong>will</strong> vary</em>!</li>
</ul>
<p>&nbsp;</p>
<h5>Like what you&#8217;ve seen here? Then why not check out <a href="http://blog.curiasolutions.com/?p=278">Round 2</a>?</h5>
<p>(Note: Please don&#8217;t leave benchmarking requests as comments. If you&#8217;d like me to take a look at your favorite framework, direct message me on twitter. Thanks!)</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/' addthis:title='The great web technology shootout &#8211; Round 1: A quick glance at the landscape ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Why I&#8217;ve fallen in love with Python</title>
		<link>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/</link>
		<comments>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 07:05:20 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=38</guid>
		<description><![CDATA[In a previous post, I briefly mentioned falling in love with Python. Now that I&#8217;m finally using Python for a large percentage of my development and am more than &#8220;casually acquainted&#8221; with its toolset, I thought it would be fun to highlight a few reasons why Python has become my new language of choice. In [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/' addthis:title='Why I&#8217;ve fallen in love with Python ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://blog.curiasolutions.com/?p=3" title="Introducing TurboGears 2">previous post</a>, I briefly mentioned falling in love with Python. Now that I&#8217;m finally using Python for a large percentage of my development and am more than &#8220;casually acquainted&#8221; with its toolset, I thought it would be fun to highlight a few reasons why Python has become my new language of choice.</p>
<p>In an effort to help you understand where I&#8217;m coming from, let me (briefly) rehash some of my programming history: I spent much of the 90&#8242;s doing dynamic web development using Perl (weren&#8217;t <em>those</em> the days!). I eventually migrated to PHP which usually made things much easier on the web; and subsequently replaced most of my console scripting with BASH [shell scripting]. However, I&#8217;m kind of a hack and love languages so I have occasionally been known to write something in C; and although I&#8217;m not a complete stranger to Java and Ruby, I never really felt like I &#8220;clicked&#8221; with either of those languages.</p>
<p>Ok, now that I&#8217;ve hopefully convinced you that I&#8217;m not just a fly-by-night programmer, let me show you some Python code. Brace yourself, as this article is bound to get lengthy&#8230; <span id="more-38"></span></p>
<blockquote><p>Reason #1: &#8220;Whitespace done right&#8221; is actually a good thing</p></blockquote>
<p>The first thing that people either absolutely love or adamantly hate about Python is the fact that code blocks are heavily tied to proper usage of whitespace. At first glance, this causes many curious onlookers from other languages to shy away from Python and continue in their bracket-encapsulated bondage. I&#8217;ll admit, at first I wasn&#8217;t too wild about these new restrictions either (I&#8217;m a programmer—I should be able to do my code how I want!); but the first time I had to go back to doing something in PHP for a client, I quickly realized I didn&#8217;t ever want to put anything inside brackets again:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># A sample function that's free from brackets, parenthesis, and semicolons!</span>
<span style="color: #ff7700;font-weight:bold;">def</span> check_number<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;That isn't a number!&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">2</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;This number is odd&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;This number is even&quot;</span></pre></div></div>

<p>Not only does this make Python source code incredibly readable, but you also end up typing less!</p>
<blockquote><p>Reason #2: I almost always know what type of object I&#8217;m working with</p></blockquote>
<p>One thing that always annoyed me about Perl was that you set an array or hash using the &#8216;@&#8217; or &#8216;%&#8217; sigils, but typically accessed them using the &#8216;$&#8217; sigil. PHP simplified this a bit, but &#8220;$array = array();&#8221; could be a simple list or an associative array (known as a dictionary in Python). With Python on the other hand, the enclosure defines the type (for most built-in types at least), and since everything is an object there&#8217;s no need for silly sigils:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># the type of enclosure makes a distinction between a string , a list, and a dictionary</span>
<span style="color: #dc143c;">string</span> = <span style="color: #483d8b;">'This is a string'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span> <span style="color: #808080; font-style: italic;"># prints 'This is a string'</span>
&nbsp;
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'This'</span>
&nbsp;
<span style="color: #008000;">dict</span> = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'first_key'</span>: <span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'second_key'</span>: <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'third_key'</span>: <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'fourth_key'</span>: <span style="color: #483d8b;">'dictionary'</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'fourth_key'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'dictionary'</span></pre></div></div>

<p>On a somewhat related note, you can use these objects on-the-fly in your scripts without even having to assign them to a name. This isn&#8217;t usually practical of course (and may not be recommended), but it is possible:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'is'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'first_key'</span>: <span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'second_key'</span>: <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'third_key'</span>: <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'fourth_key'</span>: <span style="color: #483d8b;">'dictionary'</span><span style="color: black;">&#125;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'first_key'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'This'</span></pre></div></div>

<blockquote><p>Reason #3: I can throw practically any type of object almost anywhere I want</p></blockquote>
<p>Ok, so that might be a slight exaggeration; but the truth is that since Python treats everything as an object, you&#8217;re free to pack things away in the strangest places. A great way of demonstrating the power and flexibility of Python is in an example showing a few ways different types of objects can be stored and accessed:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># create a function</span>
<span style="color: #ff7700;font-weight:bold;">def</span> hello_function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create a file handle</span>
hello_file = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'~/hello.txt'</span>, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create a list with the function, the file handle, and a string</span>
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span>hello_function, hello_file, <span style="color: #483d8b;">'Hello world!'</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!\n'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># or how about a dictionary?</span>
<span style="color: #008000;">dict</span> = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'function'</span>: hello_function, <span style="color: #483d8b;">'file_object'</span>: hello_file, <span style="color: #483d8b;">'string'</span>: <span style="color: #483d8b;">'Hello world!'</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'function'</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'file_object'</span><span style="color: black;">&#93;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!\n'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'string'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># print types</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'function'&gt;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'file_object'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'file'&gt;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'str'&gt; (str for string)</span></pre></div></div>

<p>The <em>shelve</em> and <em>pickle</em> modules are also work a look if you like what you&#8217;ve just seen here.</p>
<blockquote><p>Reason #4: The &#8220;in&#8221; operator simplifies sequences and makes membership testing a breeze</p></blockquote>
<p>To explain the power of &#8220;in&#8221;, it&#8217;s probably easier to just show you a few examples:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">'p'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #483d8b;">&quot;spam&quot;</span> <span style="color: #808080; font-style: italic;"># == True</span>
<span style="color: #483d8b;">'item1'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'item1'</span>, <span style="color: #483d8b;">'item2'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># == True</span>
<span style="color: #483d8b;">'key'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;key&quot;</span>: <span style="color: #483d8b;">'value'</span><span style="color: black;">&#125;</span> <span style="color: #808080; font-style: italic;"># == True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># prints anchor tags for a navigation</span>
<span style="color: #ff7700;font-weight:bold;">for</span> title, link <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Home'</span>: <span style="color: #483d8b;">'index.html'</span>, <span style="color: #483d8b;">'About'</span>: <span style="color: #483d8b;">'about.html'</span>, <span style="color: #483d8b;">'Contact'</span>: <span style="color: #483d8b;">'contact.html'</span><span style="color: black;">&#125;</span>.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>link, title<span style="color: black;">&#41;</span></pre></div></div>

<blockquote><p>Reason #5: Slicing, stepping, and striding are a walk in the park</p></blockquote>
<p>Probably my most-hated function in PHP is the substr() function. It should just be easier to access a parts of a string. Thankfully, in Python it&#8217;s a piece of cake:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#string slices and stepping/striding</span>
<span style="color: #dc143c;">string</span> = <span style="color: #483d8b;">'This is a string'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 's'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span>:<span style="color: #ff4500;">9</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'is a'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span>::<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Ti sasrn' (a stride of 2 means print every other item)</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># works on lists and dictionaries as well</span>
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span>::<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints ['This', 'a']</span></pre></div></div>

<blockquote><p>Reason #6-XX: Python makes programming fun again!</p></blockquote>
<p>I could go on and on, but this post would be endless. As you can see, Python is a flexible, powerful, and fun programming language. For more Python concepts (I didn&#8217;t have time here to go into list comprehensions, generators, decorators, etc), I&#8217;d suggest you take a gander at Wikipedia&#8217;s page on <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics" target="_blank">Python syntax and semantics</a>.</p>
<p>Finally, I&#8217;ll leave you with a few relevant links that are worth taking the time to check out:</p>
<ul>
<li>Bruce Eckel&#8217;s slides: <a href="http://www.mindviewinc.com/downloads/pub/eckel/LovePython.zip" target="_blank">Why I Love Python</a></li>
<li><a href="http://docs.python.org/tutorial/" target="_blank">Python&#8217;s official tutorial</a> (by Guido&mdash;Python&#8217;s creator)</li>
<li><a href="http://diveintopython.org/" target="_blank">Dive Into Python</a> &#8211; Free online book</li>
<li><a href="http://xkcd.com/353/" target="_blank">xkcd&#8217;s famous Python comic</a></li>
</ul>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/' addthis:title='Why I&#8217;ve fallen in love with Python ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Version Control Systems: My opinion so far</title>
		<link>http://blog.curiasolutions.com/2009/06/versioning-control-systems-my-opinion-so-far/</link>
		<comments>http://blog.curiasolutions.com/2009/06/versioning-control-systems-my-opinion-so-far/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 18:29:05 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[DVCS]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=8</guid>
		<description><![CDATA[There&#8217;s been a lot of noise in the development community over the last year or so about DVCS. Being highly opinionated myself, I can&#8217;t help but take a minute to share my own thoughts on the matter. Let me start by first of all saying: Yes, it&#8217;s true. Distributed Version Control Systems really are everything [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/06/versioning-control-systems-my-opinion-so-far/' addthis:title='Version Control Systems: My opinion so far ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a lot of noise in the development community over the last year or so about DVCS. Being highly opinionated myself, I can&#8217;t help but take a minute to share my own thoughts on the matter.</p>
<p>Let me start by first of all saying: Yes, it&#8217;s true. <span style="text-decoration: underline;">D</span>istributed <span style="text-decoration: underline;">V</span>ersion <span style="text-decoration: underline;">C</span>ontrol <span style="text-decoration: underline;">S</span>ystems really are everything that Centralized Version Control Systems (read: SVN/CVS) fall short on. However, having been a long-time Subversion user myself, as well as the fact that I hardly ever work on a team with more than a couple of other developers, it took a lot of noise to make me even care about the differences between DVCS and CVCS. <em>So what is the difference</em> you might ask? Almost everything; <strong>and that&#8217;s a good thing!</strong> (ok, that&#8217;s a slight exaggeration, but the benefits are so profound it almost feels that way)</p>
<p>Don&#8217;t worry, I&#8217;ll spare you the repetition of what has already been said elsewhere. My story is this: I spent about a month looking at the various DVCS&#8217; and eventually narrowed it down to Git vs Mercurial (why anyone would use Bazaar over Mercurial is beyond me). Since I&#8217;m a Linux user, and since Github impressed me, I finally decided to go with Git on the next project that came my way. Boy oh boy do I wish I had run across <a href="http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/" target="_blank">this article</a> beforehand&#8230;<span id="more-8"></span></p>
<blockquote><p>Git: MacGyver</p></blockquote>
<p>As the referenced article implies, Git does anything and everything you&#8217;d ever need it to do. Now, as a Linux guy I typically like the options I&#8217;m given with the &#8220;everything plus the kitchen sink&#8221; approach. However, I quickly found myself using 2 or 3 commands to do something I swear <em>everyone</em> must do and really should be only one command. Then there&#8217;s all the command options you have to throw in to make the command do exactly what you want it to do. This quickly became tiresome and once that project was over I decided to give Mercurial a try, hoping it would be much kinder to me.</p>
<blockquote><p>Mercurial: Bond</p></blockquote>
<p>The first thing I realized when using Mercurial on a &#8220;real&#8221; project was that it seemed to think the same way I did (an interesting trend I&#8217;ve noticed with Python programs). Whereas with Git I found myself typing &#8220;git help &lt;command&gt;&#8221; over and over again, I hardly ever needed to look up any special options with the Mercurial commands. Another thing I soon realized was that a lot of the negative press that I&#8217;d read on Mercurial was actually written up about the 1.0 version (or earlier). I was pleased to find that much of these &#8220;issues&#8221; no longer existed in my 1.2.x version of the tool.</p>
<p>I now run almost all of my new projects on Mercurial. I say &#8220;almost all&#8221; because there are a few cases where the project is small and a tool I&#8217;m using in the project already has a Git repository so it makes sense to keep everything streamlined. However, with new tools like <a href="http://hg-git.github.com/" target="_blank">hg-git</a>, even that may become a thing of the past.</p>
<p>In conclusion, I strongly encourage you to check out Mercurial if you&#8217;re jumping in to the DVCS game. Unless you&#8217;re a huge project like the Linux kernel, you probably won&#8217;t ever need the &#8220;advanced functionality&#8221; that Git puts at your fingertips (which is probably in most cases also available in Mercurial, just not right in your face). If you&#8217;re still using SVN (or even, *gasp*, CVS), then why not get with the times? Mercurial has some amazing <a href="http://www.selenic.com/mercurial/wiki/ConvertExtension" target="_blank">conversion options</a> that will retain your history and make the switch a piece of cake. Sure, there are a few new concepts to learn (pull/push and the distributed nature), but it&#8217;s only a minor learning curve that will pay off immensely.</p>
<p>&nbsp;</p>
<p>Links of interest:</p>
<ul>
<li><a href="http://www.selenic.com/mercurial" target="_blank">Mercurial</a></li>
<li><a href="http://www.bitbucket.org/" target="_blank">Bitbucket</a> &#8211; Mercurial&#8217;s version of Github</li>
<li><a href="http://en.wikipedia.org/wiki/Distributed_Version_Control_System" target="_blank">WikiPedia&#8217;s article on DVCS</a></li>
<li><a href="http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/" target="_blank">Intro to Distributed Versioning Control</a> &#8211; An excellent read</li>
<li><a href="http://mail.python.org/pipermail/python-dev/2009-March/087931.html" target="_blank">&#8220;While git has many fans, it also provokes strong antipathies.&#8221;</a> &#8211; Guido van Rossum</li>
<li><a href="http://www.youtube.com/watch?v=4XpnKHJAok8" target="_blank">&#8220;Subversion is the most pointless project ever started.&#8221;</a> &#8211; Linus Torvalds</li>
</ul>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/06/versioning-control-systems-my-opinion-so-far/' addthis:title='Version Control Systems: My opinion so far ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/06/versioning-control-systems-my-opinion-so-far/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox extensions (a.k.a. stuff I can&#8217;t live without!)</title>
		<link>http://blog.curiasolutions.com/2009/06/firefox-extensions-and-other-stuff-i-cant-live-without/</link>
		<comments>http://blog.curiasolutions.com/2009/06/firefox-extensions-and-other-stuff-i-cant-live-without/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 02:49:57 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=10</guid>
		<description><![CDATA[Note: A few months ago when I started drafting this post, Firefox v3.0 had just been released and I was enjoying it immensely. I started this post with a rant against IE (still included) and a call to Sarafi users to &#8220;get with the movement&#8221;. Well, a lot has changed since then. Safari 4 is [...]<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/06/firefox-extensions-and-other-stuff-i-cant-live-without/' addthis:title='Firefox extensions (a.k.a. stuff I can&#8217;t live without!) ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></description>
			<content:encoded><![CDATA[<p><em>Note: A few months ago when I started drafting this post, Firefox v3.0 had just been released and I was enjoying it immensely. I started this post with a rant against IE (still included) and a call to Sarafi users to &#8220;get with the movement&#8221;. Well, a lot has changed since then. Safari 4 is really slick, Google did the unthinkable and released a browser of their own, and Internet Explorer 8 actually likes web standards. So, I am finally publishing this post with a few slight updates and edits.</em></p>
<p>I&#8217;ve been playing around with Mozilla&#8217;s latest release, and I&#8217;ve got to say: Firefox is where it&#8217;s at! If anyone out there is still using Internet Explorer, you deserve anything that comes to you by way of malware, adware, spam, viruses, etc. Seriously, get with the times and install a real browser! And to you Apple/Mac users out there: Yeah, Safari is nice, but don&#8217;t let pride keep you from branching out of familiar territory.</p>
<p>One of the great thing about Firefox is its add-ons, and I&#8217;ve decided it&#8217;s time to dedicate a post to a few of my personal favorites:<span id="more-10"></span></p>
<blockquote><p><a href="http://adblockplus.org/en/" target="_blank">Adblock Plus</a></p></blockquote>
<p>To me, Adblock Plus is THE most incredible thing about Firefox (and its #1 selling point). This add-on actually strips about 99% of &#8220;web spam&#8221; and annoying banner ads from websites *before* they load into Firefox.</p>
<p>Note: Some web sites are financed soley by revenue from visitors loading ads on their sites. Keep in mind that stripping out ads may in some cases also affect the income generated by your favorite blog/social site.</p>
<blockquote><p><a href="http://flashblock.mozdev.org/" target="_blank">Flashblock</a></p></blockquote>
<p>Similar to Adblock, Flashblock turns flash elements into &#8220;play buttons&#8221; instead of auto-playing all those crazy flash items on pages.</p>
<blockquote><p><a href="http://getfirebug.com/" target="_blank">Firebug</a></p></blockquote>
<p>To me, the 2nd most important thing about Firefox. As a web developer I&#8217;m always having to dissect a page&#8217;s DOM, or do extra debugging on a JavaScript function. Firebug gives me complete access, control and information about a web page.</p>
<blockquote><p><a href="http://tamperdata.mozdev.org/" target="_blank">Tamper Data</a></p></blockquote>
<p>A more technical add-on, Tamper Data allows you to view and modify request headers and form submits (as well as any other communication between the client &amp; server). Very geeky, but very powerful.</p>
<blockquote><p><a href="http://fireftp.mozdev.org/" target="_blank">FireFTP</a></p></blockquote>
<p>FireFTP turns Firefox into a full-featured FTP client. A must, especially if you&#8217;re a Windows user (mounting FTP sites in Windows Explorer is still weird)</p>
<p>&nbsp;</p>
<p>Honorable mention: <a href="http://code.google.com/p/sqlite-manager/" target="_blank">SQLite Manager</a>, <a href="http://chatzilla.hacksrus.com/" target="_blank">ChatZilla</a>, <a href="http://foxyproxy.mozdev.org/" target="_blank">FoxyProxy</a>, <a href="http://www.shaneliesegang.com/projects/coffee.php" target="_blank">Morning Coffee</a>, <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a>, <a href="http://chrispederick.com/work/user-agent-switcher/" target="_blank">User Agent Switcher</a></p>
<p>&nbsp;</p>
<p>Give these a whirl&#8230; you&#8217;ll be glad you did!</p>
<p>- Seth</p>
<div class="addthis_toolbox addthis_default_style" addthis:url='http://blog.curiasolutions.com/2009/06/firefox-extensions-and-other-stuff-i-cant-live-without/' addthis:title='Firefox extensions (a.k.a. stuff I can&#8217;t live without!) ' ><a class="addthis_button_google_plusone" g:plusone:size="medium" ></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/06/firefox-extensions-and-other-stuff-i-cant-live-without/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

