<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0"><channel><title>bytetrap</title><link>http://www.bytetrap.com/</link><description>Latest blog entries from bytetrap.</description><language>en-us</language><lastBuildDate>Thu, 16 Jul 2009 12:01:51 -0000</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/bytetrap" type="application/rss+xml" /><item><title>Lazy Evaluation in AS3
</title><link>http://www.bytetrap.com/blog/2009/06/24/lazy-evaluation-as3/</link><description>&lt;p&gt;
&lt;a href="http://en.wikipedia.org/wiki/Lazy_evaluation"&gt;Lazy evaluation&lt;/a&gt; is a useful practice for any programmer who wants to cut down on unnecessary processing. There's no need to break it out if it's not necessary; especially if the language (Actionscript) is ill suited to it. There are cases though where delaying computation until the result is required lets lazy evaluation slice off the extra computational gristle that's slowing down my code.  &lt;br/&gt;
I ran into a situation a few days ago that really benefited from the lazy approach. I had a class named Vector2 which handled 2-dimension computation, as described below. &lt;/p&gt;

&lt;pre&gt;
//Vector2 with Eager Evaluation
public class Vector2 {
	
	private var _x:Number;
	private var _y:Number;
	private var _length:Number;

	public function Vector2( x:Number = 0, y:Number = 0 ) {
		setXY( x, y );
	}

	public function setXY( x:Number, y:Number ):void {
		_x = x;
		_y = y;
		_length = Math.sqrt( _x * _x + _y * _y );  //length is computed as soon as x and y are set
	}

	public function get x():Number {
		return _x;
	}
		
	public function get y():Number {
		return _y;
	}
	public function get length():Number {
		return _length;
	}
} 
&lt;/pre&gt;

&lt;p&gt;
The issue arose when dealing with the &lt;strong&gt;_length&lt;/strong&gt; value in a Vector2. The square root in determining the &lt;strong&gt;_length&lt;/strong&gt; of a Vector2 was computationally intensive and often unnecessary. It was a rare occasion when I needed the length of a vector; most of the time I produced vectors for minor computations that never needed a calculation of length. Therefore, I wanted to delay the computation of the length of the vector until it was absolutely necessary. &lt;br/&gt;
Simultaneously, I didn't want a &lt;strong&gt;getLength()&lt;/strong&gt; function, because I didn't want to have to recompute the length every time I asked for it. I wanted to compute the length once, the moment I asked for it, and save that result for future references. However, if in the future I changed the &lt;strong&gt;_x&lt;/strong&gt; or &lt;strong&gt;_y&lt;/strong&gt;, I needed some way to tell my program that the length of the vector needed to be recomputed the next time I requested it. &lt;br/&gt;
Lazy evaluation magically fulfills all my requirements.
&lt;/p&gt;
&lt;h3&gt; Implementing Lazy Evaluation&lt;/h3&gt;
&lt;p&gt;
Flash is an Eagerly Evaluated language though, how can one implement Lazy Evaluation? 
&lt;/p&gt;

&lt;pre&gt;
//Vector2 with Lazy Evaluation
//Code not directly applicable to the example has been removed
public class Vector2 {
	
	private var _x:Number;
	private var _y:Number;
	private var _length:Number;
	private var lengthFunction:Function;

	public function Vector2( x:Number = 0, y:Number = 0 ) {
		_x = x;
		_y = y;
		lengthFunction = function() { 
			_length = Math.sqrt( _x * _x + _y * _y ); 
		};
	}

	public function set x( newX:Number ):void {
		_x = newX;
		lengthFunction = function():void {
			_length = Math.sqrt( _x * _x + _y * _y );
		}
	}
	public function set y( newY:Number ):void {
		_y = newY;
		lengthFunction = function():void {
			_length = Math.sqrt( _x * _x + _y * _y );
		}
	}
	public function get x():Number {
		return _x;
	}
		
	public function get y():Number {
		return _y;
	}
	public function get length():Number {
		lengthFunction();    //recomputes the length of the Vector2 if necessary
		lengthFunction = function():void {}    //replaces the length function with an empty function call
		return _length;
	}
}
&lt;/pre&gt;

&lt;p&gt;
The Vector2 class written above achieves lazy evaluation through Flash's &lt;a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html"&gt;Function&lt;/a&gt; class. When I request the length of my Vector2, the &lt;strong&gt;lengthFunction&lt;/strong&gt; (an object of a function) is called, and the length is returned. The &lt;strong&gt;lengthFunction&lt;/strong&gt; is where all the lazy magic happens. 
&lt;/p&gt;
&lt;p&gt;
Whenever the &lt;strong&gt;_x&lt;/strong&gt; or &lt;strong&gt;_y&lt;/strong&gt; value is altered, the &lt;strong&gt;lengthFunction&lt;/strong&gt; is set to &lt;strong&gt;Math.sqrt( _x * _x + _y * _y )&lt;/strong&gt;. Once the length is evaluated however, it reassigns itself to an empty function. Next time I ask for the length of my Vector2, the processor will run through an empty function call rather than the computationally intensive square root calculation.
&lt;/p&gt;
&lt;p&gt;
This class uses a number of getter and setter methods which I have heard are rather slow, but that doesn't detract from the practical merit of this practice. It's like helping a friend move into a new apartment, you have to know when to avoid the unnecessary heavy lifting.
&lt;/p&gt;
</description><guid>http://www.bytetrap.com/blog/2009/06/24/lazy-evaluation-as3/</guid></item><item><title>Setting Up a Shared Remote Git Repository
</title><link>http://www.bytetrap.com/blog/2009/05/25/setting-shared-remote-git-repository/</link><description>&lt;p&gt;Here is a good article on &lt;a
href="http://toolmantim.com/articles/setting_up_a_new_remote_git_repository"&gt;setting
up a new remote git repository&lt;/a&gt;. Here are additional steps to create a
shared repository which allows multiple users to contribute to the same
repository. First, add &lt;strong&gt;sharedrepository = 1&lt;/strong&gt; in the
&lt;strong&gt;config&lt;/strong&gt; file of the repository:&lt;/p&gt;

&lt;pre&gt;
[core]
    repositoryformatversion = 0
    filemode = true
    sharedrepository = 1
&lt;/pre&gt;

&lt;p&gt;Create a new system group for users who should have access to the
repository. Add the users into the group:&lt;/p&gt;

&lt;pre&gt;
$ groupadd git
$ gpasswd -a ryan
&lt;/pre&gt;

&lt;p&gt;Next, set up secure permissions on the repository. Start by changing the
ownership of the files in the repository to root and the group specified
above:&lt;/p&gt;

&lt;pre&gt;
$ cd /var/git/project.git
$ chown -R root:git .
&lt;/pre&gt;

&lt;p&gt;Remove access to the repository from everybody except the user and group:&lt;/p&gt;

&lt;pre&gt;
chmod -R o-rwx .
&lt;/pre&gt;

&lt;p&gt;The group should have the same permisisons as the user:&lt;/p&gt;

&lt;pre&gt;
chmod -R g=u .
&lt;/pre&gt;

&lt;p&gt;Add the &lt;strong&gt;s&lt;/strong&gt; flag on the group permissions for all directories
in the repository. This will give processes that tries to access the
directories the necessary privileges to add and modify content within the directories.
This is necessary to allow multiple external users to commit to the
repository:&lt;/p&gt;

&lt;pre&gt;
find . -type d | xargs chmod g+s
&lt;/pre&gt;

&lt;p&gt;That's it. The repository should be set and good to go.&lt;/p&gt;
</description><guid>http://www.bytetrap.com/blog/2009/05/25/setting-shared-remote-git-repository/</guid></item><item><title>Delay Function Call in AS3
</title><link>http://www.bytetrap.com/blog/2009/04/13/delay-function-call-as3/</link><description>&lt;p&gt;
I have a confession to make - I've been seeing another language. &lt;br/&gt;
I'm sorry &lt;a href="http://en.wikipedia.org/wiki/Actionscript"&gt;AS3&lt;/a&gt;, but &lt;a href="http://en.wikipedia.org/wiki/Scheme_(programming_language)"&gt;Scheme&lt;/a&gt; is just so much more elegant that you.
&lt;/p&gt;
&lt;p&gt;
I've decided to focus more on the functional aspects of AS3 after fooling around with Scheme for the last semester or so. All of what I'm about to say could be done with more explicit objects, but I think that would be masking the idea behind this code.
&lt;/p&gt;
&lt;p&gt;
I'm working on a new game where a little man on a raft is hunted by God. God, in his old testament (and vaguely Zeusish) rage, hurls bolts of lightning, summons storms, and calls really enormous fish to smite this poor little dude. I wanted my lightning strikes to come in delayed intervals (first bolt at 1 second, second bolt at 3 seconds, etc... ), but I didn't want to explicitly call a timer every time. I wanted a more general solution to the problem. Then I found out that AS3 was pretty good at passing functions as objects.
&lt;/p&gt;

&lt;h2&gt; Code &lt;/h2&gt;
The following code sets up our example.
Cut and paste it into the timeline to run it. &lt;br/&gt;

&lt;pre&gt;
//Create a new Sprite that is a child of the stage
Var testSprite:Sprite = new Sprite();
addChild( testSprite );

//draw a rectangle in the sprite
testSprite.graphics.beginFill( 0x0000FF, 1 );
testSprite.graphics.drawRect( 0,0, 200 200 ); //the function we're going to delay
testSprite.graphics.endFill()

&lt;/pre&gt;
&lt;p&gt;
Now we're going to delay the function call &lt;strong&gt; drawRect(...)&lt;/strong&gt;. Replace your previous code with the following.&lt;br/&gt;
The Function object has an &lt;strong&gt;.apply&lt;/strong&gt;  function, which takes the object the function is called on, and the arguments (in the form of an array) passed to that function.
&lt;/p&gt;
&lt;pre&gt;
//Create a new Sprite that is a child of the stage
Var testSprite:Sprite = new Sprite();
addChild( testSprite );

//draw a rectangle in the sprite
testSprite.graphics.beginFill( 0x0000FF, 1 );

//you'll notice that we're not calling the function, just passing its reference.
Var delayFunction:Function = testSprite.graphics.drawRect;  

//the arguments provided for the function
var arguments:Array = [ 0, 0, 200, 200 ];

//a simple timer to delay the function call
var timer:Timer = new Timer( 1000, 1);
timer.addEventListener( TimerEvent.TIMER, runFunction );
timer.start();

//our function that listens to the timer, waiting for it to ring before running
protected function runFunction( event:Event ):void {
			
	delayFunction.apply( testSprite.graphics, args );
	testSprite.graphics.endFill()
			
}
&lt;/pre&gt;
&lt;p&gt;
Warnings about this method of programming. Make sure your object doesn't get dereferenced between when you create the function and when it gets applied (that should throw you some errors).
Now for the more general case. Here is a little class I programmed that delays function calls.
&lt;/p&gt;
&lt;pre&gt;
package {
	
	import flash.events.Event;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	/**
	 * Delays before running the function
	 * @author Daniel Fast
	 */
	public class WaitThenDo {
		
		protected var timer:Timer;
		
		protected var delayFunction:Function;
		protected var args:Array;
		protected var obj:Object;
		
		/**
		 * delay a number of seconds before running the function
		 */
		public function WaitThenDo( func:Function, obj:Object, args:Array, delay:Number, repeat:Number = 1 ):void {
			
			this.args = args;
			this.delayFunction = func;
			this.obj = obj;
			
			timer = new Timer( delay * 1000, repeat );
			timer.addEventListener( TimerEvent.TIMER, runFunction );
			timer.start();
			
		}
		
		protected function runFunction( event:Event ):void {
			
			delayFunction.apply( obj, args );
			
		}
		
	}
	
}
&lt;/pre&gt;
</description><guid>http://www.bytetrap.com/blog/2009/04/13/delay-function-call-as3/</guid></item><item><title>Formatting a USB Stick in Arch Linux
</title><link>http://www.bytetrap.com/blog/2009/04/13/formatting-usb-stick-arch-linux/</link><description>&lt;p&gt;My USB stick goofed the other day. The file system became corrupted and my
system had difficulty properly reading from and writing to the device.
Fortunately my system was still able to recognize the stick, allowing me to
fix it without too much effort. Regardless, I'm writing this short
entry on how to format a USB stick because I'm bound to run into this problem
again.&lt;/p&gt;

&lt;h2&gt;Partitioning the USB Stick&lt;/h2&gt;

&lt;p&gt;The easiest way to fix a corrupted file system is to simply delete the damn
partition and start from scratch. You won't be able to salvage any files from
the stick but it's a quick and painless solution to have a working device
again. First, connect the USB stick into your computer and figure out the
device name:&lt;/p&gt;

&lt;pre&gt;
$ dmesg |tail
sd 6:0:0:0: [sdb] Mode Sense: 00 00 00 00
sd 6:0:0:0: [sdb] Assuming drive cache: write through
sd 6:0:0:0: [sdb] 15794175 512-byte hardware sectors: (8.08 GB/7.53 GiB)
sd 6:0:0:0: [sdb] Write Protect is off
sd 6:0:0:0: [sdb] Mode Sense: 00 00 00 00
sd 6:0:0:0: [sdb] Assuming drive cache: write through
 sdb: sdb1
sd 6:0:0:0: [sdb] Attached SCSI removable disk
sd 6:0:0:0: Attached scsi generic sg2 type 0
usb-storage: device scan complete
&lt;/pre&gt;

&lt;p&gt;Then use &lt;strong&gt;fdisk&lt;/strong&gt; to delete all existing partitions on the
stick and create a new one. Use the default values when creating a new
partition:&lt;/p&gt;

&lt;pre&gt;
$ fdisk /dev/sdb
&lt;/pre&gt;

&lt;p&gt;Now you need to create a new file system. You definitely don't want to use a
&lt;a href="http://en.wikipedia.org/wiki/Journaling_file system"&gt;journaling
file system&lt;/a&gt; like &lt;strong&gt;ext3&lt;/strong&gt; because writing to the device will be
much slower and some space will be wasted for the journal. Also it will
be incompatible with machines using Windows. Use &lt;strong&gt;VFAT&lt;/strong&gt; instead.
You will need the &lt;strong&gt;dosfstools&lt;/strong&gt; package to be able to create that
file system:&lt;/p&gt;

&lt;pre&gt;
$ pacman -Sy dosfstools
&lt;/pre&gt;

&lt;p&gt;Create the file system on the stick:&lt;/p&gt;

&lt;pre&gt;
$ mkfs.vfat /dev/sdb1
&lt;/pre&gt;

&lt;p&gt;Try mounting the stick. It should work:&lt;/p&gt;

&lt;pre&gt;
$ mount /dev/sdb1 /media/usb
&lt;/pre&gt;

&lt;h2&gt;Recovering Data&lt;/h2&gt;

&lt;p&gt;If you need to recover data, here is an &lt;a
href="http://www.linuxjournal.com/article/8366"&gt;article&lt;/a&gt; on how you could
possibly salvage the data on a corrupted stick. I haven't tested it so I can't verify how well it works.&lt;/p&gt;
</description><guid>http://www.bytetrap.com/blog/2009/04/13/formatting-usb-stick-arch-linux/</guid></item><item><title>Django Benchmark: mod_python vs. mod_wsgi
</title><link>http://www.bytetrap.com/blog/2009/02/22/django-benchmark-mod_python-vs-mod_wsgi/</link><description>&lt;p&gt;There are already &lt;a
href="http://www.technobabble.dk/2008/aug/25/django-mod-wsgi-perfect-match/"&gt; a
couple of articles&lt;/a&gt; out there that conclusively state that &lt;a
href="http://code.google.com/p/modwsgi/"&gt;mod_wsgi&lt;/a&gt; has a lower memory
overhead and performs better than &lt;a
href="http://www.modpython.org/"&gt;mod_python&lt;/a&gt;. I did a lot of digging around
but couldn't find any concrete data on how much performance I would gain by
switching to mod_wsgi.
Since I was planning on switching over my &lt;a
href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; projects anyway, I decided to do
a benchmark test to see what the numbers looked like.&lt;/p&gt;

&lt;h2&gt;Methodology&lt;/h2&gt;

&lt;p&gt;I conducted the test on my laptop (&lt;a
href="http://www.thinkwiki.org/wiki/Category:T60"&gt;ThinkPad T60&lt;/a&gt;), which has
the following specifications:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2.0GHz Intel Core Duo (Yonah) T2500, 2MB of L2 cache&lt;/li&gt;
  &lt;li&gt;1GB of RAM&lt;/li&gt;
  &lt;li&gt;Arch Linux 2.6.28 i686&lt;/li&gt;
  &lt;li&gt;Apache 2.2.11, Pre-Fork MPM&lt;/li&gt;
  &lt;li&gt;mod_python 3.3.1&lt;/li&gt;
  &lt;li&gt;mod_wsgi 2.3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used the base &lt;strong&gt;httpd.conf&lt;/strong&gt; file that came from the default
Arch Linux install. The analysis is derived from a load test performed using
&lt;strong&gt;ab&lt;/strong&gt;, aka ApacheBench (v2.3). I measured performance in terms
of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Number of requests served per second.&lt;/li&gt;
  &lt;li&gt;Latency response time in milliseconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The demo site used to measure performance is a simple Hello World
application, so only static content was used. The load test was run twice, the
first time using both mod_wsgi and the second time using mod_python. Each test
was run independently and followed these steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The machine is rebooted; destroying extranneous child
  processes created between tests and flushing the memory and cache.
  It is necessary to maintain consistency across all tests.&lt;/li&gt;
  &lt;li&gt;Run the load test. Each test starts with 1 concurrent users and the load
  is increased by intervals of 10 to a maximum load of 200 users. Each interval consists of 5 simulations,
  and its average is used for the graphs. Each simulation simulates 1000 requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Results&lt;/h2&gt;

&lt;p&gt;Here is the raw data gathered from the test:&lt;/p&gt;

&lt;h2&gt;Requests per Second (mod_python) &lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Concurrency&lt;/th&gt;
      &lt;th&gt;Run 1&lt;/th&gt;
      &lt;th&gt;Run 2&lt;/th&gt;
      &lt;th&gt;Run 3&lt;/th&gt;
      &lt;th&gt;Run 4&lt;/th&gt;
      &lt;th&gt;Run 5&lt;/th&gt;
      &lt;th&gt;Average&lt;/th&gt;
      &lt;th&gt;± σ&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;506.11&lt;/td&gt;
      &lt;td&gt;513.13&lt;/td&gt;
      &lt;td&gt;451.93&lt;/td&gt;
      &lt;td&gt;513.78&lt;/td&gt;
      &lt;td&gt;460.18&lt;/td&gt;
      &lt;td&gt;489.03&lt;/td&gt;
      &lt;td&gt;30.39&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;809.37&lt;/td&gt;
      &lt;td&gt;889.26&lt;/td&gt;
      &lt;td&gt;828.37&lt;/td&gt;
      &lt;td&gt;765.17&lt;/td&gt;
      &lt;td&gt;764.91&lt;/td&gt;
      &lt;td&gt;811.42&lt;/td&gt;
      &lt;td&gt;51.60&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;781.22&lt;/td&gt;
      &lt;td&gt;814.43&lt;/td&gt;
      &lt;td&gt;768.44&lt;/td&gt;
      &lt;td&gt;397.53&lt;/td&gt;
      &lt;td&gt;911.77&lt;/td&gt;
      &lt;td&gt;734.68&lt;/td&gt;
      &lt;td&gt;196.66&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;742.19&lt;/td&gt;
      &lt;td&gt;779.90&lt;/td&gt;
      &lt;td&gt;716.17&lt;/td&gt;
      &lt;td&gt;651.84&lt;/td&gt;
      &lt;td&gt;690.45&lt;/td&gt;
      &lt;td&gt;716.11&lt;/td&gt;
      &lt;td&gt;48.83&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;734.50&lt;/td&gt;
      &lt;td&gt;723.39&lt;/td&gt;
      &lt;td&gt;760.76&lt;/td&gt;
      &lt;td&gt;543.60&lt;/td&gt;
      &lt;td&gt;418.64&lt;/td&gt;
      &lt;td&gt;636.18&lt;/td&gt;
      &lt;td&gt;148.90&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;50&lt;/td&gt;
      &lt;td&gt;725.84&lt;/td&gt;
      &lt;td&gt;704.99&lt;/td&gt;
      &lt;td&gt;687.82&lt;/td&gt;
      &lt;td&gt;620.58&lt;/td&gt;
      &lt;td&gt;694.27&lt;/td&gt;
      &lt;td&gt;686.70&lt;/td&gt;
      &lt;td&gt;39.68&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;60&lt;/td&gt;
      &lt;td&gt;739.61&lt;/td&gt;
      &lt;td&gt;742.00&lt;/td&gt;
      &lt;td&gt;564.42&lt;/td&gt;
      &lt;td&gt;669.93&lt;/td&gt;
      &lt;td&gt;697.10&lt;/td&gt;
      &lt;td&gt;682.61&lt;/td&gt;
      &lt;td&gt;72.66&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt;719.93&lt;/td&gt;
      &lt;td&gt;741.36&lt;/td&gt;
      &lt;td&gt;758.58&lt;/td&gt;
      &lt;td&gt;761.72&lt;/td&gt;
      &lt;td&gt;603.25&lt;/td&gt;
      &lt;td&gt;716.97&lt;/td&gt;
      &lt;td&gt;65.71&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;80&lt;/td&gt;
      &lt;td&gt;755.55&lt;/td&gt;
      &lt;td&gt;608.91&lt;/td&gt;
      &lt;td&gt;729.43&lt;/td&gt;
      &lt;td&gt;704.57&lt;/td&gt;
      &lt;td&gt;641.06&lt;/td&gt;
      &lt;td&gt;687.90&lt;/td&gt;
      &lt;td&gt;61.26&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;90&lt;/td&gt;
      &lt;td&gt;735.95&lt;/td&gt;
      &lt;td&gt;710.01&lt;/td&gt;
      &lt;td&gt;695.61&lt;/td&gt;
      &lt;td&gt;559.32&lt;/td&gt;
      &lt;td&gt;387.32&lt;/td&gt;
      &lt;td&gt;617.64&lt;/td&gt;
      &lt;td&gt;145.82&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;670.18&lt;/td&gt;
      &lt;td&gt;634.93&lt;/td&gt;
      &lt;td&gt;703.91&lt;/td&gt;
      &lt;td&gt;717.19&lt;/td&gt;
      &lt;td&gt;661.85&lt;/td&gt;
      &lt;td&gt;677.61&lt;/td&gt;
      &lt;td&gt;33.10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;110&lt;/td&gt;
      &lt;td&gt;668.30&lt;/td&gt;
      &lt;td&gt;696.03&lt;/td&gt;
      &lt;td&gt;663.72&lt;/td&gt;
      &lt;td&gt;714.04&lt;/td&gt;
      &lt;td&gt;685.37&lt;/td&gt;
      &lt;td&gt;685.49&lt;/td&gt;
      &lt;td&gt;20.59&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;120&lt;/td&gt;
      &lt;td&gt;691.75&lt;/td&gt;
      &lt;td&gt;702.94&lt;/td&gt;
      &lt;td&gt;723.24&lt;/td&gt;
      &lt;td&gt;662.35&lt;/td&gt;
      &lt;td&gt;467.70&lt;/td&gt;
      &lt;td&gt;649.60&lt;/td&gt;
      &lt;td&gt;104.04&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;130&lt;/td&gt;
      &lt;td&gt;347.04&lt;/td&gt;
      &lt;td&gt;725.80&lt;/td&gt;
      &lt;td&gt;708.91&lt;/td&gt;
      &lt;td&gt;694.92&lt;/td&gt;
      &lt;td&gt;716.96&lt;/td&gt;
      &lt;td&gt;638.73&lt;/td&gt;
      &lt;td&gt;163.45&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;140&lt;/td&gt;
      &lt;td&gt;677.47&lt;/td&gt;
      &lt;td&gt;690.62&lt;/td&gt;
      &lt;td&gt;686.36&lt;/td&gt;
      &lt;td&gt;686.08&lt;/td&gt;
      &lt;td&gt;723.11&lt;/td&gt;
      &lt;td&gt;692.73&lt;/td&gt;
      &lt;td&gt;17.64&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt;736.96&lt;/td&gt;
      &lt;td&gt;730.58&lt;/td&gt;
      &lt;td&gt;713.07&lt;/td&gt;
      &lt;td&gt;640.02&lt;/td&gt;
      &lt;td&gt;546.07&lt;/td&gt;
      &lt;td&gt;673.34&lt;/td&gt;
      &lt;td&gt;80.95&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;h2&gt;Requests per Second (mod_wsgi) &lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Concurrency&lt;/th&gt;
      &lt;th&gt;Run 1&lt;/th&gt;
      &lt;th&gt;Run 2&lt;/th&gt;
      &lt;th&gt;Run 3&lt;/th&gt;
      &lt;th&gt;Run 4&lt;/th&gt;
      &lt;th&gt;Run 5&lt;/th&gt;
      &lt;th&gt;Average&lt;/th&gt;
      &lt;th&gt;± σ&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;497.09&lt;/td&gt;
      &lt;td&gt;508.48&lt;/td&gt;
      &lt;td&gt;499.23&lt;/td&gt;
      &lt;td&gt;510.04&lt;/td&gt;
      &lt;td&gt;505.59&lt;/td&gt;
      &lt;td&gt;504.09&lt;/td&gt;
      &lt;td&gt;5.69&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;890.19&lt;/td&gt;
      &lt;td&gt;845.55&lt;/td&gt;
      &lt;td&gt;798.46&lt;/td&gt;
      &lt;td&gt;834.20&lt;/td&gt;
      &lt;td&gt;844.81&lt;/td&gt;
      &lt;td&gt;842.64&lt;/td&gt;
      &lt;td&gt;32.78&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;824.96&lt;/td&gt;
      &lt;td&gt;700.34&lt;/td&gt;
      &lt;td&gt;583.10&lt;/td&gt;
      &lt;td&gt;848.99&lt;/td&gt;
      &lt;td&gt;810.46&lt;/td&gt;
      &lt;td&gt;753.57&lt;/td&gt;
      &lt;td&gt;111.05&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;781.50&lt;/td&gt;
      &lt;td&gt;825.53&lt;/td&gt;
      &lt;td&gt;738.09&lt;/td&gt;
      &lt;td&gt;720.25&lt;/td&gt;
      &lt;td&gt;740.55&lt;/td&gt;
      &lt;td&gt;761.18&lt;/td&gt;
      &lt;td&gt;42.39&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;810.62&lt;/td&gt;
      &lt;td&gt;792.99&lt;/td&gt;
      &lt;td&gt;829.81&lt;/td&gt;
      &lt;td&gt;809.80&lt;/td&gt;
      &lt;td&gt;830.41&lt;/td&gt;
      &lt;td&gt;814.73&lt;/td&gt;
      &lt;td&gt;15.71&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;50&lt;/td&gt;
      &lt;td&gt;819.01&lt;/td&gt;
      &lt;td&gt;827.41&lt;/td&gt;
      &lt;td&gt;864.42&lt;/td&gt;
      &lt;td&gt;727.75&lt;/td&gt;
      &lt;td&gt;799.78&lt;/td&gt;
      &lt;td&gt;807.67&lt;/td&gt;
      &lt;td&gt;50.47&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;60&lt;/td&gt;
      &lt;td&gt;798.28&lt;/td&gt;
      &lt;td&gt;626.20&lt;/td&gt;
      &lt;td&gt;789.92&lt;/td&gt;
      &lt;td&gt;874.75&lt;/td&gt;
      &lt;td&gt;749.22&lt;/td&gt;
      &lt;td&gt;767.67&lt;/td&gt;
      &lt;td&gt;91.18&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt;814.53&lt;/td&gt;
      &lt;td&gt;803.98&lt;/td&gt;
      &lt;td&gt;659.83&lt;/td&gt;
      &lt;td&gt;498.84&lt;/td&gt;
      &lt;td&gt;784.61&lt;/td&gt;
      &lt;td&gt;712.36&lt;/td&gt;
      &lt;td&gt;134.54&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;80&lt;/td&gt;
      &lt;td&gt;745.46&lt;/td&gt;
      &lt;td&gt;627.36&lt;/td&gt;
      &lt;td&gt;763.28&lt;/td&gt;
      &lt;td&gt;802.21&lt;/td&gt;
      &lt;td&gt;777.89&lt;/td&gt;
      &lt;td&gt;743.24&lt;/td&gt;
      &lt;td&gt;68.03&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;90&lt;/td&gt;
      &lt;td&gt;784.43&lt;/td&gt;
      &lt;td&gt;783.72&lt;/td&gt;
      &lt;td&gt;790.53&lt;/td&gt;
      &lt;td&gt;713.44&lt;/td&gt;
      &lt;td&gt;478.60&lt;/td&gt;
      &lt;td&gt;710.14&lt;/td&gt;
      &lt;td&gt;133.25&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;322.69&lt;/td&gt;
      &lt;td&gt;826.19&lt;/td&gt;
      &lt;td&gt;803.53&lt;/td&gt;
      &lt;td&gt;790.29&lt;/td&gt;
      &lt;td&gt;837.32&lt;/td&gt;
      &lt;td&gt;716.00&lt;/td&gt;
      &lt;td&gt;220.64&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;110&lt;/td&gt;
      &lt;td&gt;787.18&lt;/td&gt;
      &lt;td&gt;761.44&lt;/td&gt;
      &lt;td&gt;765.44&lt;/td&gt;
      &lt;td&gt;685.14&lt;/td&gt;
      &lt;td&gt;759.73&lt;/td&gt;
      &lt;td&gt;751.79&lt;/td&gt;
      &lt;td&gt;38.85&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;120&lt;/td&gt;
      &lt;td&gt;798.28&lt;/td&gt;
      &lt;td&gt;789.82&lt;/td&gt;
      &lt;td&gt;781.68&lt;/td&gt;
      &lt;td&gt;727.36&lt;/td&gt;
      &lt;td&gt;780.56&lt;/td&gt;
      &lt;td&gt;775.54&lt;/td&gt;
      &lt;td&gt;27.86&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;130&lt;/td&gt;
      &lt;td&gt;804.60&lt;/td&gt;
      &lt;td&gt;808.80&lt;/td&gt;
      &lt;td&gt;829.83&lt;/td&gt;
      &lt;td&gt;849.97&lt;/td&gt;
      &lt;td&gt;744.16&lt;/td&gt;
      &lt;td&gt;807.47&lt;/td&gt;
      &lt;td&gt;39.76&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;140&lt;/td&gt;
      &lt;td&gt;800.70&lt;/td&gt;
      &lt;td&gt;691.09&lt;/td&gt;
      &lt;td&gt;438.41&lt;/td&gt;
      &lt;td&gt;414.73&lt;/td&gt;
      &lt;td&gt;621.90&lt;/td&gt;
      &lt;td&gt;593.37&lt;/td&gt;
      &lt;td&gt;165.28&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt;756.59&lt;/td&gt;
      &lt;td&gt;747.22&lt;/td&gt;
      &lt;td&gt;780.77&lt;/td&gt;
      &lt;td&gt;756.80&lt;/td&gt;
      &lt;td&gt;799.11&lt;/td&gt;
      &lt;td&gt;768.10&lt;/td&gt;
      &lt;td&gt;21.32&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;h2&gt;Time per Request (mean) (mod_python)&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Concurrency&lt;/th&gt;
      &lt;th&gt;Run 1&lt;/th&gt;
      &lt;th&gt;Run 2&lt;/th&gt;
      &lt;th&gt;Run 3&lt;/th&gt;
      &lt;th&gt;Run 4&lt;/th&gt;
      &lt;th&gt;Run 5&lt;/th&gt;
      &lt;th&gt;Average&lt;/th&gt;
      &lt;th&gt;± σ&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;1.976&lt;/td&gt;
      &lt;td&gt;1.949&lt;/td&gt;
      &lt;td&gt;2.213&lt;/td&gt;
      &lt;td&gt;1.946&lt;/td&gt;
      &lt;td&gt;2.173&lt;/td&gt;
      &lt;td&gt;2.051&lt;/td&gt;
      &lt;td&gt;0.131&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;12.355&lt;/td&gt;
      &lt;td&gt;11.245&lt;/td&gt;
      &lt;td&gt;12.072&lt;/td&gt;
      &lt;td&gt;13.069&lt;/td&gt;
      &lt;td&gt;13.073&lt;/td&gt;
      &lt;td&gt;12.363&lt;/td&gt;
      &lt;td&gt;0.764&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;25.601&lt;/td&gt;
      &lt;td&gt;24.557&lt;/td&gt;
      &lt;td&gt;26.027&lt;/td&gt;
      &lt;td&gt;50.310&lt;/td&gt;
      &lt;td&gt;21.935&lt;/td&gt;
      &lt;td&gt;29.686&lt;/td&gt;
      &lt;td&gt;11.638&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;40.421&lt;/td&gt;
      &lt;td&gt;38.466&lt;/td&gt;
      &lt;td&gt;41.890&lt;/td&gt;
      &lt;td&gt;46.024&lt;/td&gt;
      &lt;td&gt;43.450&lt;/td&gt;
      &lt;td&gt;42.050&lt;/td&gt;
      &lt;td&gt;2.884&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;54.459&lt;/td&gt;
      &lt;td&gt;55.295&lt;/td&gt;
      &lt;td&gt;52.579&lt;/td&gt;
      &lt;td&gt;73.583&lt;/td&gt;
      &lt;td&gt;95.547&lt;/td&gt;
      &lt;td&gt;66.293&lt;/td&gt;
      &lt;td&gt;18.426&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;50&lt;/td&gt;
      &lt;td&gt;68.886&lt;/td&gt;
      &lt;td&gt;70.923&lt;/td&gt;
      &lt;td&gt;72.683&lt;/td&gt;
      &lt;td&gt;80.569&lt;/td&gt;
      &lt;td&gt;72.018&lt;/td&gt;
      &lt;td&gt;73.016&lt;/td&gt;
      &lt;td&gt;4.461&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;60&lt;/td&gt;
      &lt;td&gt;81.124&lt;/td&gt;
      &lt;td&gt;80.863&lt;/td&gt;
      &lt;td&gt;106.303&lt;/td&gt;
      &lt;td&gt;89.562&lt;/td&gt;
      &lt;td&gt;86.071&lt;/td&gt;
      &lt;td&gt;88.785&lt;/td&gt;
      &lt;td&gt;10.444&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt;97.232&lt;/td&gt;
      &lt;td&gt;94.422&lt;/td&gt;
      &lt;td&gt;92.277&lt;/td&gt;
      &lt;td&gt;91.897&lt;/td&gt;
      &lt;td&gt;116.038&lt;/td&gt;
      &lt;td&gt;98.373&lt;/td&gt;
      &lt;td&gt;10.100&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;80&lt;/td&gt;
      &lt;td&gt;105.883&lt;/td&gt;
      &lt;td&gt;131.382&lt;/td&gt;
      &lt;td&gt;109.675&lt;/td&gt;
      &lt;td&gt;113.544&lt;/td&gt;
      &lt;td&gt;124.793&lt;/td&gt;
      &lt;td&gt;117.055&lt;/td&gt;
      &lt;td&gt;10.686&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;90&lt;/td&gt;
      &lt;td&gt;122.291&lt;/td&gt;
      &lt;td&gt;126.758&lt;/td&gt;
      &lt;td&gt;129.383&lt;/td&gt;
      &lt;td&gt;160.909&lt;/td&gt;
      &lt;td&gt;232.364&lt;/td&gt;
      &lt;td&gt;154.341&lt;/td&gt;
      &lt;td&gt;46.211&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;149.214&lt;/td&gt;
      &lt;td&gt;157.498&lt;/td&gt;
      &lt;td&gt;142.063&lt;/td&gt;
      &lt;td&gt;139.433&lt;/td&gt;
      &lt;td&gt;151.092&lt;/td&gt;
      &lt;td&gt;147.860&lt;/td&gt;
      &lt;td&gt;7.242&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;110&lt;/td&gt;
      &lt;td&gt;164.597&lt;/td&gt;
      &lt;td&gt;158.040&lt;/td&gt;
      &lt;td&gt;165.732&lt;/td&gt;
      &lt;td&gt;154.052&lt;/td&gt;
      &lt;td&gt;160.498&lt;/td&gt;
      &lt;td&gt;160.584&lt;/td&gt;
      &lt;td&gt;4.789&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;120&lt;/td&gt;
      &lt;td&gt;173.474&lt;/td&gt;
      &lt;td&gt;170.712&lt;/td&gt;
      &lt;td&gt;165.921&lt;/td&gt;
      &lt;td&gt;181.174&lt;/td&gt;
      &lt;td&gt;256.575&lt;/td&gt;
      &lt;td&gt;189.571&lt;/td&gt;
      &lt;td&gt;37.862&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;130&lt;/td&gt;
      &lt;td&gt;374.591&lt;/td&gt;
      &lt;td&gt;179.113&lt;/td&gt;
      &lt;td&gt;183.380&lt;/td&gt;
      &lt;td&gt;187.072&lt;/td&gt;
      &lt;td&gt;181.321&lt;/td&gt;
      &lt;td&gt;221.095&lt;/td&gt;
      &lt;td&gt;85.857&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;140&lt;/td&gt;
      &lt;td&gt;206.651&lt;/td&gt;
      &lt;td&gt;202.717&lt;/td&gt;
      &lt;td&gt;203.974&lt;/td&gt;
      &lt;td&gt;204.060&lt;/td&gt;
      &lt;td&gt;193.608&lt;/td&gt;
      &lt;td&gt;202.202&lt;/td&gt;
      &lt;td&gt;5.013&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt;203.538&lt;/td&gt;
      &lt;td&gt;205.316&lt;/td&gt;
      &lt;td&gt;210.359&lt;/td&gt;
      &lt;td&gt;234.366&lt;/td&gt;
      &lt;td&gt;274.690&lt;/td&gt;
      &lt;td&gt;225.654&lt;/td&gt;
      &lt;td&gt;30.071&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2&gt;Time per Request (mean) (mod_wsgi)&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Concurrency&lt;/th&gt;
      &lt;th&gt;Run 1&lt;/th&gt;
      &lt;th&gt;Run 2&lt;/th&gt;
      &lt;th&gt;Run 3&lt;/th&gt;
      &lt;th&gt;Run 4&lt;/th&gt;
      &lt;th&gt;Run 5&lt;/th&gt;
      &lt;th&gt;Average&lt;/th&gt;
      &lt;th&gt;± σ&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2.012&lt;/td&gt;
      &lt;td&gt;1.967&lt;/td&gt;
      &lt;td&gt;2.003&lt;/td&gt;
      &lt;td&gt;1.961&lt;/td&gt;
      &lt;td&gt;1.978&lt;/td&gt;
      &lt;td&gt;1.984&lt;/td&gt;
      &lt;td&gt;0.022&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;11.234&lt;/td&gt;
      &lt;td&gt;11.827&lt;/td&gt;
      &lt;td&gt;12.524&lt;/td&gt;
      &lt;td&gt;11.988&lt;/td&gt;
      &lt;td&gt;11.837&lt;/td&gt;
      &lt;td&gt;11.882&lt;/td&gt;
      &lt;td&gt;0.461&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt;24.244&lt;/td&gt;
      &lt;td&gt;28.557&lt;/td&gt;
      &lt;td&gt;34.299&lt;/td&gt;
      &lt;td&gt;23.558&lt;/td&gt;
      &lt;td&gt;24.677&lt;/td&gt;
      &lt;td&gt;27.067&lt;/td&gt;
      &lt;td&gt;4.487&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;38.388&lt;/td&gt;
      &lt;td&gt;36.340&lt;/td&gt;
      &lt;td&gt;40.646&lt;/td&gt;
      &lt;td&gt;41.652&lt;/td&gt;
      &lt;td&gt;40.510&lt;/td&gt;
      &lt;td&gt;39.507&lt;/td&gt;
      &lt;td&gt;2.132&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;49.345&lt;/td&gt;
      &lt;td&gt;50.422&lt;/td&gt;
      &lt;td&gt;48.204&lt;/td&gt;
      &lt;td&gt;49.395&lt;/td&gt;
      &lt;td&gt;48.169&lt;/td&gt;
      &lt;td&gt;49.107&lt;/td&gt;
      &lt;td&gt;0.944&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;50&lt;/td&gt;
      &lt;td&gt;61.049&lt;/td&gt;
      &lt;td&gt;60.429&lt;/td&gt;
      &lt;td&gt;57.842&lt;/td&gt;
      &lt;td&gt;68.705&lt;/td&gt;
      &lt;td&gt;62.517&lt;/td&gt;
      &lt;td&gt;62.108&lt;/td&gt;
      &lt;td&gt;4.057&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;60&lt;/td&gt;
      &lt;td&gt;75.162&lt;/td&gt;
      &lt;td&gt;95.816&lt;/td&gt;
      &lt;td&gt;75.957&lt;/td&gt;
      &lt;td&gt;68.591&lt;/td&gt;
      &lt;td&gt;80.083&lt;/td&gt;
      &lt;td&gt;79.122&lt;/td&gt;
      &lt;td&gt;10.201&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt;85.939&lt;/td&gt;
      &lt;td&gt;87.067&lt;/td&gt;
      &lt;td&gt;106.087&lt;/td&gt;
      &lt;td&gt;140.324&lt;/td&gt;
      &lt;td&gt;89.216&lt;/td&gt;
      &lt;td&gt;101.727&lt;/td&gt;
      &lt;td&gt;23.073&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;80&lt;/td&gt;
      &lt;td&gt;107.317&lt;/td&gt;
      &lt;td&gt;127.519&lt;/td&gt;
      &lt;td&gt;104.811&lt;/td&gt;
      &lt;td&gt;99.724&lt;/td&gt;
      &lt;td&gt;102.842&lt;/td&gt;
      &lt;td&gt;108.443&lt;/td&gt;
      &lt;td&gt;11.020&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;90&lt;/td&gt;
      &lt;td&gt;114.733&lt;/td&gt;
      &lt;td&gt;114.836&lt;/td&gt;
      &lt;td&gt;113.848&lt;/td&gt;
      &lt;td&gt;126.149&lt;/td&gt;
      &lt;td&gt;188.049&lt;/td&gt;
      &lt;td&gt;131.523&lt;/td&gt;
      &lt;td&gt;32.003&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;309.895&lt;/td&gt;
      &lt;td&gt;121.038&lt;/td&gt;
      &lt;td&gt;124.451&lt;/td&gt;
      &lt;td&gt;126.536&lt;/td&gt;
      &lt;td&gt;119.428&lt;/td&gt;
      &lt;td&gt;160.270&lt;/td&gt;
      &lt;td&gt;83.690&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;110&lt;/td&gt;
      &lt;td&gt;139.740&lt;/td&gt;
      &lt;td&gt;144.463&lt;/td&gt;
      &lt;td&gt;143.709&lt;/td&gt;
      &lt;td&gt;160.552&lt;/td&gt;
      &lt;td&gt;144.788&lt;/td&gt;
      &lt;td&gt;146.650&lt;/td&gt;
      &lt;td&gt;8.030&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;120&lt;/td&gt;
      &lt;td&gt;150.322&lt;/td&gt;
      &lt;td&gt;151.934&lt;/td&gt;
      &lt;td&gt;153.515&lt;/td&gt;
      &lt;td&gt;164.979&lt;/td&gt;
      &lt;td&gt;153.736&lt;/td&gt;
      &lt;td&gt;154.897&lt;/td&gt;
      &lt;td&gt;5.801&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;130&lt;/td&gt;
      &lt;td&gt;161.570&lt;/td&gt;
      &lt;td&gt;160.732&lt;/td&gt;
      &lt;td&gt;156.659&lt;/td&gt;
      &lt;td&gt;152.947&lt;/td&gt;
      &lt;td&gt;174.693&lt;/td&gt;
      &lt;td&gt;161.320&lt;/td&gt;
      &lt;td&gt;8.232&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;140&lt;/td&gt;
      &lt;td&gt;174.846&lt;/td&gt;
      &lt;td&gt;202.583&lt;/td&gt;
      &lt;td&gt;319.334&lt;/td&gt;
      &lt;td&gt;337.565&lt;/td&gt;
      &lt;td&gt;225.118&lt;/td&gt;
      &lt;td&gt;251.889&lt;/td&gt;
      &lt;td&gt;72.410&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class="odd"&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt;198.258&lt;/td&gt;
      &lt;td&gt;200.743&lt;/td&gt;
      &lt;td&gt;192.118&lt;/td&gt;
      &lt;td&gt;198.203&lt;/td&gt;
      &lt;td&gt;187.708&lt;/td&gt;
      &lt;td&gt;195.406&lt;/td&gt;
      &lt;td&gt;5.350&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;And here are the graphs. These are much more telling:&lt;/p&gt;

&lt;img alt="requests" src="/media/blog/2009/02/22/requests.png"/&gt;
&lt;img alt="time" src="/media/blog/2009/02/22/time.png"/&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;On average mod_wsgi is able to serve &lt;strong&gt;9.6%&lt;/strong&gt; more
  requests than mod_python.&lt;/li&gt;
  &lt;li&gt;The standard deviation for requests per second using mod_wsgi is
  &lt;strong&gt;6.9%&lt;/strong&gt; lower than mod_python. This could be due to
  accident, or this could imply that mod_python is not as stable and consistent as
  mod_wsgi.&lt;/li&gt;
  &lt;li&gt;On average mod_wsgi was able to serve requests &lt;strong&gt;8.8%&lt;/strong&gt;
  faster than mod_python.&lt;/li&gt;
  &lt;li&gt;Again, the standard deviation for time per request using mod_wsgi is
  &lt;strong&gt;5.4%&lt;/strong&gt; lower than mod_python.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't think I can draw any conclusions from the standard deviations
without doing a little more testing. But it seems pretty clear from looking at
the raw digits and the graphs that mod_wsgi performs better than
mod_python. It would be interesting to see how mod_wsgi measures up in a
real-world environment.&lt;/p&gt;
</description><guid>http://www.bytetrap.com/blog/2009/02/22/django-benchmark-mod_python-vs-mod_wsgi/</guid></item></channel></rss>
