<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Static File Shootout: Apache RewriteRules vs. Flask</title>
	<atom:link href="http://blog.mozilla.org/webdev/2013/03/08/3303/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.org/webdev/2013/03/08/3303/</link>
	<description>Engineering the web</description>
	<lastBuildDate>Fri, 17 May 2013 21:43:21 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
	<item>
		<title>By: Erik Rose</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228713</link>
		<dc:creator>Erik Rose</dc:creator>
		<pubDate>Wed, 13 Mar 2013 16:57:32 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228713</guid>
		<description><![CDATA[The GIL in particular thing is really a shame. It would be interesting to run some benchmarks on real hardware with different numbers of threads per process, on both IO and CPU-bound jobs.]]></description>
		<content:encoded><![CDATA[<p>The GIL in particular thing is really a shame. It would be interesting to run some benchmarks on real hardware with different numbers of threads per process, on both IO and CPU-bound jobs.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hanno Schlichting</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228710</link>
		<dc:creator>Hanno Schlichting</dc:creator>
		<pubDate>Wed, 13 Mar 2013 11:14:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228710</guid>
		<description><![CDATA[If you have time for more experimentation, you could look at:

- X-Sendfile (http://flask.pocoo.org/docs/api/#flask.Flask.use_x_sendfile)

Seems to be supported by Flask, but needs an Apache module. This causes the Python app to just emit the headers of the response, including a special X-Sendfile one. The X-Sendfile header tells the Apache process the filesystem path of the file and lets it handle the actual sending of the data, including kernel-level sendfile support, so the file isn&#039;t even loaded into Apache&#039;s memory. Nginx implements the same idea (http://wiki.nginx.org/XSendfile).

- FileWrapperExtension (http://code.google.com/p/modwsgi/wiki/FileWrapperExtension)

This is a similar Python/WSGI specific idea of the above, but there seem to be more cases where it fails or needs extra configuration.

- Use Python 3.2&#039;s new GIL (http://docs.python.org/3/whatsnew/3.2.html#multi-threading)

It seems mod_wgsi 3 supports Python 3. If the application doesn&#039;t do much else, you could try running it under Python 3.2 to take advantage of the new GIL / thread scheduling. I&#039;d expect this to give more uniform response times and help with the 90%+ times.
If you are interested in the back story, there&#039;s lots of information in Dave Beazley&#039;s blog posts about the GIL (http://www.dabeaz.com/blog.html).

- Use taskset to pin processes to CPU&#039;s

The taskset command allows one to pin a process to a specific CPU. If you have multiple processes and threads, the default scheduling often ends up trying to schedule one or more threads of the same Python process on different CPU cores. But the GIL often prevents them from actually executing in parallel. The net result for any given thread is, that it&#039;s more or less randomly executed on all CPU cores, which destroys all the L1/L2 caches or even memory access times in NUMA systems.

For the number of processes/threads, it&#039;s indeed best to do actual experimentation and measurements. Most general advice out there suggests to oversubscribe and have twice as many threads as CPU cores. But that usually only holds true for applications with a mixed CPU and i/o load.]]></description>
		<content:encoded><![CDATA[<p>If you have time for more experimentation, you could look at:</p>
<p>- X-Sendfile (<a href="http://flask.pocoo.org/docs/api/#flask.Flask.use_x_sendfile" rel="nofollow">http://flask.pocoo.org/docs/api/#flask.Flask.use_x_sendfile</a>)</p>
<p>Seems to be supported by Flask, but needs an Apache module. This causes the Python app to just emit the headers of the response, including a special X-Sendfile one. The X-Sendfile header tells the Apache process the filesystem path of the file and lets it handle the actual sending of the data, including kernel-level sendfile support, so the file isn&#8217;t even loaded into Apache&#8217;s memory. Nginx implements the same idea (<a href="http://wiki.nginx.org/XSendfile" rel="nofollow">http://wiki.nginx.org/XSendfile</a>).</p>
<p>- FileWrapperExtension (<a href="http://code.google.com/p/modwsgi/wiki/FileWrapperExtension" rel="nofollow">http://code.google.com/p/modwsgi/wiki/FileWrapperExtension</a>)</p>
<p>This is a similar Python/WSGI specific idea of the above, but there seem to be more cases where it fails or needs extra configuration.</p>
<p>- Use Python 3.2&#8242;s new GIL (<a href="http://docs.python.org/3/whatsnew/3.2.html#multi-threading" rel="nofollow">http://docs.python.org/3/whatsnew/3.2.html#multi-threading</a>)</p>
<p>It seems mod_wgsi 3 supports Python 3. If the application doesn&#8217;t do much else, you could try running it under Python 3.2 to take advantage of the new GIL / thread scheduling. I&#8217;d expect this to give more uniform response times and help with the 90%+ times.<br />
If you are interested in the back story, there&#8217;s lots of information in Dave Beazley&#8217;s blog posts about the GIL (<a href="http://www.dabeaz.com/blog.html" rel="nofollow">http://www.dabeaz.com/blog.html</a>).</p>
<p>- Use taskset to pin processes to CPU&#8217;s</p>
<p>The taskset command allows one to pin a process to a specific CPU. If you have multiple processes and threads, the default scheduling often ends up trying to schedule one or more threads of the same Python process on different CPU cores. But the GIL often prevents them from actually executing in parallel. The net result for any given thread is, that it&#8217;s more or less randomly executed on all CPU cores, which destroys all the L1/L2 caches or even memory access times in NUMA systems.</p>
<p>For the number of processes/threads, it&#8217;s indeed best to do actual experimentation and measurements. Most general advice out there suggests to oversubscribe and have twice as many threads as CPU cores. But that usually only holds true for applications with a mixed CPU and i/o load.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Erik Rose</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228678</link>
		<dc:creator>Erik Rose</dc:creator>
		<pubDate>Mon, 11 Mar 2013 17:36:46 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228678</guid>
		<description><![CDATA[I didn&#039;t know about X-Sendfile when I did the benchmarking, but I almost used it by accident. Take a look at the code snippet where I use send_from_directory(). That calls send_file() under the covers, which &quot;will use the most efficient method available and configured. By default it will try to use the WSGI server’s file_wrapper support. Alternatively you can set the application’s use_x_sendfile attribute to True to directly emit an X-Sendfile header. This however requires support of the underlying webserver for X-Sendfile.&quot;

So, I&#039;m basically one attribute-set and an Apache module away from doing that. If I try it, I&#039;ll update the results here. :-)]]></description>
		<content:encoded><![CDATA[<p>I didn&#8217;t know about X-Sendfile when I did the benchmarking, but I almost used it by accident. Take a look at the code snippet where I use send_from_directory(). That calls send_file() under the covers, which &#8220;will use the most efficient method available and configured. By default it will try to use the WSGI server’s file_wrapper support. Alternatively you can set the application’s use_x_sendfile attribute to True to directly emit an X-Sendfile header. This however requires support of the underlying webserver for X-Sendfile.&#8221;</p>
<p>So, I&#8217;m basically one attribute-set and an Apache module away from doing that. If I try it, I&#8217;ll update the results here. <img src='http://blog.mozilla.org/webdev/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Robert</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228653</link>
		<dc:creator>Robert</dc:creator>
		<pubDate>Sat, 09 Mar 2013 23:29:14 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228653</guid>
		<description><![CDATA[^ I was also going to say such a thing, but tell you to look at mod_wsgi&#039;s sendfile options.]]></description>
		<content:encoded><![CDATA[<p>^ I was also going to say such a thing, but tell you to look at mod_wsgi&#8217;s sendfile options.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nils Maier</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228646</link>
		<dc:creator>Nils Maier</dc:creator>
		<pubDate>Sat, 09 Mar 2013 02:05:25 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228646</guid>
		<description><![CDATA[May I offer a shameless plug and ask if you tried or considered https://tn123.org/mod_xsendfile/ already?]]></description>
		<content:encoded><![CDATA[<p>May I offer a shameless plug and ask if you tried or considered <a href="https://tn123.org/mod_xsendfile/" rel="nofollow">https://tn123.org/mod_xsendfile/</a> already?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Erik Rose</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228645</link>
		<dc:creator>Erik Rose</dc:creator>
		<pubDate>Fri, 08 Mar 2013 22:55:03 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228645</guid>
		<description><![CDATA[The resource type shouldn&#039;t make a difference at this level. It&#039;s just bytes; we aren&#039;t involving a browser. The only relevant piece is the size of the resource, which in this case was 7348 bytes. Indeed, that is part of the multidimensional soup, as you point out.

I wouldn&#039;t expect network speed to play much into the results, since either Apache or Python should be able to keep up with any reasonable pipe. However, slow readers could plug up Python threads, reducing the pool for everybody else.

That said, there are certainly many other variables to explore!]]></description>
		<content:encoded><![CDATA[<p>The resource type shouldn&#8217;t make a difference at this level. It&#8217;s just bytes; we aren&#8217;t involving a browser. The only relevant piece is the size of the resource, which in this case was 7348 bytes. Indeed, that is part of the multidimensional soup, as you point out.</p>
<p>I wouldn&#8217;t expect network speed to play much into the results, since either Apache or Python should be able to keep up with any reasonable pipe. However, slow readers could plug up Python threads, reducing the pool for everybody else.</p>
<p>That said, there are certainly many other variables to explore!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: karl</title>
		<link>http://blog.mozilla.org/webdev/2013/03/08/3303/comment-page-1/#comment-228644</link>
		<dc:creator>karl</dc:creator>
		<pubDate>Fri, 08 Mar 2013 22:45:50 +0000</pubDate>
		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3303#comment-228644</guid>
		<description><![CDATA[Did you try with different type of resources? html, css, js, etc.

and also studying the variability along different file sizes.

Finally the last thing would be to see how it behaves and how much the performance is impacted in a test with different type of bandwidth. The latency of networks usually dwarfes the local performance issues.]]></description>
		<content:encoded><![CDATA[<p>Did you try with different type of resources? html, css, js, etc.</p>
<p>and also studying the variability along different file sizes.</p>
<p>Finally the last thing would be to see how it behaves and how much the performance is impacted in a test with different type of bandwidth. The latency of networks usually dwarfes the local performance issues.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
