<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments for Willem Stuursma</title>
	<atom:link href="http://willem.stuursma.name/comments/feed/" rel="self" type="application/rss+xml" />
	<link>http://willem.stuursma.name</link>
	<description>Passionate on product and programming</description>
	<lastBuildDate>Tue, 31 Jan 2012 10:14:10 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>Comment on HipHop for PHP at Hyves by tjerkw</title>
		<link>http://willem.stuursma.name/2011/12/12/hiphop-for-php-at-hyves/#comment-254</link>
		<dc:creator><![CDATA[tjerkw]]></dc:creator>
		<pubDate>Tue, 31 Jan 2012 10:14:10 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=386#comment-254</guid>
		<description><![CDATA[@Morg just saying that 3.5 LOL is a fail is a bit short sighted. Do you even know what the code does? Rewriting the whole shabang to C++ is also not a good option, since it will cost a lot of money and would increase the number of lines even more because of the fact that PHP is on a higher abstraction level. I&#039;m not saying PHP is perfect. However I would not choose C++ as a language to rewrite it in. Also a rewrite comes with a lot of costs. Look for example at Marktplaats who rewrote their whole site to Java. This took ~2 years to complete.

However I can understand your woohooo at the 3.5M and 500MB executable. However your conclusions are to short sighted.]]></description>
		<content:encoded><![CDATA[<p>@Morg just saying that 3.5 LOL is a fail is a bit short sighted. Do you even know what the code does? Rewriting the whole shabang to C++ is also not a good option, since it will cost a lot of money and would increase the number of lines even more because of the fact that PHP is on a higher abstraction level. I&#8217;m not saying PHP is perfect. However I would not choose C++ as a language to rewrite it in. Also a rewrite comes with a lot of costs. Look for example at Marktplaats who rewrote their whole site to Java. This took ~2 years to complete.</p>
<p>However I can understand your woohooo at the 3.5M and 500MB executable. However your conclusions are to short sighted.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Going to work at Hyves by Xuxu</title>
		<link>http://willem.stuursma.name/2010/06/01/going-to-work-at-hyves/#comment-251</link>
		<dc:creator><![CDATA[Xuxu]]></dc:creator>
		<pubDate>Thu, 12 Jan 2012 11:44:11 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=226#comment-251</guid>
		<description><![CDATA[oh,surprisingly you are an interaction designer:) lot&#039;s of my friends are~~and focus on &quot;real&quot; product usability(not meaning ur work is vain:P but just different area, virtual products sometimes are more attractive than real ones;)). But  it is fun to know your focus is on user experience:&gt;]]></description>
		<content:encoded><![CDATA[<p>oh,surprisingly you are an interaction designer:) lot&#8217;s of my friends are~~and focus on &#8220;real&#8221; product usability(not meaning ur work is vain:P but just different area, virtual products sometimes are more attractive than real ones;)). But  it is fun to know your focus is on user experience:&gt;</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on HipHop for PHP at Hyves by Morg.</title>
		<link>http://willem.stuursma.name/2011/12/12/hiphop-for-php-at-hyves/#comment-236</link>
		<dc:creator><![CDATA[Morg.]]></dc:creator>
		<pubDate>Thu, 29 Dec 2011 10:09:21 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=386#comment-236</guid>
		<description><![CDATA[3.5 M LOC in PHP ? sounds like major fail to me . 

Also, the very idea of starting with PHP and then using a tool to convert it in half-assed c++ .

Has it occured to the tech management @ Hyves that rewriting the whole thing in C++ could be more interesting ?

Good thing though that you point out how much even fail C++ is better than PHP.

Then again, 500MB for a compiled binary : your company should invest in making their code a bit cleaner . 500MB is enough for an OS with many packages, how can you justify taking that much space for a web app (even if it has quite a few options) ?

I know I&#039;m being annoying, but seriously, if you really are the guy who says &quot;I want to write software that doesn&#039;t suck.&quot; ... you might want to consider reality : something like Hyves should at most take 5MB of code - anymore means its a convoluted mess of copy/pasting, spaghetti and 99% unused libraries.]]></description>
		<content:encoded><![CDATA[<p>3.5 M LOC in PHP ? sounds like major fail to me . </p>
<p>Also, the very idea of starting with PHP and then using a tool to convert it in half-assed c++ .</p>
<p>Has it occured to the tech management @ Hyves that rewriting the whole thing in C++ could be more interesting ?</p>
<p>Good thing though that you point out how much even fail C++ is better than PHP.</p>
<p>Then again, 500MB for a compiled binary : your company should invest in making their code a bit cleaner . 500MB is enough for an OS with many packages, how can you justify taking that much space for a web app (even if it has quite a few options) ?</p>
<p>I know I&#8217;m being annoying, but seriously, if you really are the guy who says &#8220;I want to write software that doesn&#8217;t suck.&#8221; &#8230; you might want to consider reality : something like Hyves should at most take 5MB of code &#8211; anymore means its a convoluted mess of copy/pasting, spaghetti and 99% unused libraries.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on A detailed look into array_map() and foreach by Morg.</title>
		<link>http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/#comment-222</link>
		<dc:creator><![CDATA[Morg.]]></dc:creator>
		<pubDate>Thu, 15 Dec 2011 10:31:33 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=313#comment-222</guid>
		<description><![CDATA[Good . 

I was in my shower yesterday when I thought it could be due to function call overhead.. unfortunately my benchmark actually did something relatively dumb in order to make the example realistic, I used a function wrapper around htmlentities.. thus getting into function call overhead territory.

As I measured before, function call overhead can easily put you at +50% running time.

Thing is . this is much bigger than I thought, and array_map could simply be faster than looping :

countdown for done in :0.66113471984863ms
countup for done in :0.76103210449219ms
countdown while done in :0.63705444335938ms
countup while done in :0.63014030456543ms
foreach done in :0.62894821166992ms
array_map w/ func wrapper done in :0.75912475585938ms
array_map w/o func wrapper done in :0.53882598876953ms


I don&#039;t know why you use hphp, it looks like it&#039;s overall more inefficient - but w/e.

a) don&#039;t use anonymous functions when focusing on performance.
b) make real benchmarks
c) question your benchmarks
d) profit !

I changed the last part to do this :

$a=$a0;
$start=microtime(true);
array_map(&#039;htmlentities&#039;,$a);
echo &#039;array_map w/o func wrapper done in :&#039;.(microtime(true)-$start)*1000 . &#039;ms&#039;;

This gives us completely different results and is a real use case of array_map (i.e. you&#039;ve got a function to apply. you&#039;re not creating it for that purpose, it&#039;s already there, defined and required and you would use it even if you iterated manually).]]></description>
		<content:encoded><![CDATA[<p>Good . </p>
<p>I was in my shower yesterday when I thought it could be due to function call overhead.. unfortunately my benchmark actually did something relatively dumb in order to make the example realistic, I used a function wrapper around htmlentities.. thus getting into function call overhead territory.</p>
<p>As I measured before, function call overhead can easily put you at +50% running time.</p>
<p>Thing is . this is much bigger than I thought, and array_map could simply be faster than looping :</p>
<p>countdown for done in :0.66113471984863ms<br />
countup for done in :0.76103210449219ms<br />
countdown while done in :0.63705444335938ms<br />
countup while done in :0.63014030456543ms<br />
foreach done in :0.62894821166992ms<br />
array_map w/ func wrapper done in :0.75912475585938ms<br />
array_map w/o func wrapper done in :0.53882598876953ms</p>
<p>I don&#8217;t know why you use hphp, it looks like it&#8217;s overall more inefficient &#8211; but w/e.</p>
<p>a) don&#8217;t use anonymous functions when focusing on performance.<br />
b) make real benchmarks<br />
c) question your benchmarks<br />
d) profit !</p>
<p>I changed the last part to do this :</p>
<p>$a=$a0;<br />
$start=microtime(true);<br />
array_map(&#8216;htmlentities&#8217;,$a);<br />
echo &#8216;array_map w/o func wrapper done in :&#8217;.(microtime(true)-$start)*1000 . &#8216;ms&#8217;;</p>
<p>This gives us completely different results and is a real use case of array_map (i.e. you&#8217;ve got a function to apply. you&#8217;re not creating it for that purpose, it&#8217;s already there, defined and required and you would use it even if you iterated manually).</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on A detailed look into array_map() and foreach by stuursma</title>
		<link>http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/#comment-221</link>
		<dc:creator><![CDATA[stuursma]]></dc:creator>
		<pubDate>Wed, 14 Dec 2011 16:52:03 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=313#comment-221</guid>
		<description><![CDATA[Thank you for your insightful comment on this one particular aspect that I mentioned! I created a small script to do the benchmarks again. 
&lt;pre&gt;
&lt;?php
define(&#039;ARRAY_SIZE&#039;, 512);
define(&#039;RUNS&#039;, 1e4);

function benchmark($function, $desc) {
	$total_time = 0;
	for($i = 0; $i &lt; RUNS; $i++) {	
		$total_time += $function();
	}
	echo sprintf(&#039;%dx %s took %.5f seconds&#039; . PHP_EOL, RUNS, $desc, $total_time);
}

benchmark(function() {
	$r = range(0, ARRAY_SIZE);
	$start = microtime(true);
	foreach ($r as $k =&gt; $v) {
	for($i = 0; $i  $v) {
		$r[$k] =&gt; $v * $v;
	}
	return microtime(true) - $start;
}, &#039;foreach&#039;);

benchmark(function() {	
	$r = range(0, ARRAY_SIZE);
	$start = microtime(true);
	$r = array_map(function($each) { return $each * $eacha; }, $r);	
	return microtime(true) - $start;
}, &#039;array_map&#039;);
&lt;/pre&gt;
So this script will calculate the squares of all the elements in a 512 elements sized array 10,000 times. 

Using PHP 5.3, I got the following results:
&lt;pre&gt;
$ php bench.php 
10000x foreach took 1.14517 seconds
10000x array_map took 1.66716 seconds
&lt;/pre&gt;

So it seems that you were right, it is not 6 times as slow but more like 70% as slow.

I think I might have accidentally ran the benchmark with the Hiphop interpreter instead of PHP:
&lt;pre&gt;
$ hphp bench.php 
10000x foreach took 1.77771 seconds
10000x array_map took 4.84831 seconds
&lt;/pre&gt;
With HPHP, array_map() is about 2.8x as slow as using foreach. 

I have updated the article to reflect these benchmarks. However, as I mentioned in the article, in most scenarios the time it takes to iterate over the array is negligible compared to the time spend in the loop or anonymous function. So this performance difference does not really matter.]]></description>
		<content:encoded><![CDATA[<p>Thank you for your insightful comment on this one particular aspect that I mentioned! I created a small script to do the benchmarks again. </p>
<pre>
&lt;?php
define(&#039;ARRAY_SIZE&#039;, 512);
define(&#039;RUNS&#039;, 1e4);

function benchmark($function, $desc) {
	$total_time = 0;
	for($i = 0; $i &lt; RUNS; $i++) {
		$total_time += $function();
	}
	echo sprintf('%dx %s took %.5f seconds' . PHP_EOL, RUNS, $desc, $total_time);
}

benchmark(function() {
	$r = range(0, ARRAY_SIZE);
	$start = microtime(true);
	foreach ($r as $k =&gt; $v) {
	for($i = 0; $i  $v) {
		$r[$k] =&gt; $v * $v;
	}
	return microtime(true) - $start;
}, 'foreach');

benchmark(function() {
	$r = range(0, ARRAY_SIZE);
	$start = microtime(true);
	$r = array_map(function($each) { return $each * $eacha; }, $r);
	return microtime(true) - $start;
}, 'array_map');
</pre>
<p>So this script will calculate the squares of all the elements in a 512 elements sized array 10,000 times. </p>
<p>Using PHP 5.3, I got the following results:</p>
<pre>
$ php bench.php
10000x foreach took 1.14517 seconds
10000x array_map took 1.66716 seconds
</pre>
<p>So it seems that you were right, it is not 6 times as slow but more like 70% as slow.</p>
<p>I think I might have accidentally ran the benchmark with the Hiphop interpreter instead of PHP:</p>
<pre>
$ hphp bench.php
10000x foreach took 1.77771 seconds
10000x array_map took 4.84831 seconds
</pre>
<p>With HPHP, array_map() is about 2.8x as slow as using foreach. </p>
<p>I have updated the article to reflect these benchmarks. However, as I mentioned in the article, in most scenarios the time it takes to iterate over the array is negligible compared to the time spend in the loop or anonymous function. So this performance difference does not really matter.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on A detailed look into array_map() and foreach by Morg.</title>
		<link>http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/#comment-219</link>
		<dc:creator><![CDATA[Morg.]]></dc:creator>
		<pubDate>Wed, 14 Dec 2011 15:49:22 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=313#comment-219</guid>
		<description><![CDATA[This is misinformation. big time.

You picked a really bad example and put a general title above it, this might influence new coders to think array_map is 6 times slower than foreach, and that&#039;s just wrong.]]></description>
		<content:encoded><![CDATA[<p>This is misinformation. big time.</p>
<p>You picked a really bad example and put a general title above it, this might influence new coders to think array_map is 6 times slower than foreach, and that&#8217;s just wrong.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Parallel array_map() with HipHop by HipHop for PHP at Hyves &#171; Willem Stuursma</title>
		<link>http://willem.stuursma.name/2011/09/08/parallel-array_map-with-hiphop/#comment-218</link>
		<dc:creator><![CDATA[HipHop for PHP at Hyves &#171; Willem Stuursma]]></dc:creator>
		<pubDate>Mon, 12 Dec 2011 17:27:17 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=346#comment-218</guid>
		<description><![CDATA[[...] has some really cool features. There is a call_user_func_async() function (it does exactly what it says), and you can have two versions of you web site running at [...]]]></description>
		<content:encoded><![CDATA[<p>[...] has some really cool features. There is a call_user_func_async() function (it does exactly what it says), and you can have two versions of you web site running at [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Some experiences using Facebook&#8217;s HPHP / Hiphop by Parallel array_map() with Hiphop &#171; Willem Stuursma</title>
		<link>http://willem.stuursma.name/2011/06/12/some-experiences-using-facebooks-hphp-hiphop/#comment-172</link>
		<dc:creator><![CDATA[Parallel array_map() with Hiphop &#171; Willem Stuursma]]></dc:creator>
		<pubDate>Thu, 08 Sep 2011 19:55:22 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=335#comment-172</guid>
		<description><![CDATA[[...] the past it has been very hard to effectively use parallelization in PHP. However, with Facebook&#8217;s Hiphop Facebook engineers have added the option to create threads in PHP using the call_user_func_async() [...]]]></description>
		<content:encoded><![CDATA[<p>[...] the past it has been very hard to effectively use parallelization in PHP. However, with Facebook&#8217;s Hiphop Facebook engineers have added the option to create threads in PHP using the call_user_func_async() [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Some experiences using Facebook&#8217;s HPHP / Hiphop by Ot</title>
		<link>http://willem.stuursma.name/2011/06/12/some-experiences-using-facebooks-hphp-hiphop/#comment-168</link>
		<dc:creator><![CDATA[Ot]]></dc:creator>
		<pubDate>Sun, 12 Jun 2011 22:01:29 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=335#comment-168</guid>
		<description><![CDATA[Nice. Not into PHP myself, but I like the concept. A similar thing exists for Python, by the way.]]></description>
		<content:encoded><![CDATA[<p>Nice. Not into PHP myself, but I like the concept. A similar thing exists for Python, by the way.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Don&#8217;t use persistent connections to MySQL in PHP by Nikhil Mohan</title>
		<link>http://willem.stuursma.name/2010/04/25/dont-use-persistent-connections-to-mysql-in-php/#comment-144</link>
		<dc:creator><![CDATA[Nikhil Mohan]]></dc:creator>
		<pubDate>Fri, 17 Dec 2010 07:45:46 +0000</pubDate>
		<guid isPermaLink="false">http://willem.stuursma.name/?p=211#comment-144</guid>
		<description><![CDATA[Here&#039;s a nifty little class which will load balance across multiple replicated MySQL server instances, using persistent connections, automatically removing failed MySQL servers from the pool.
  
You would ONLY use this for queries, never inserts/updates/deletes, UNLESS you had a multi-master situation where updates to any database serverautomatically replicate to the other servers (I don&#039;t know whether that&#039;s possible with MySQL).

Using this class, you get a connection to a MySQL server like this:
    
$con = MySQLConnectionFactory::create();

Here is the class (you&#039;ll need to customize the $SERVERS array for your configuration -- note that you would probably use the same username, password and database for all of the servers, just changing the host name, but you&#039;re not forced to use the same ones):

&lt;? php
class MySQLConnectionFactory {
    
static $SERVERS = array(
    
array(
        
&#039;host&#039; =&gt; &#039;myHost1&#039;,
        
&#039;username&#039; =&gt; &#039;myUsername1&#039;,
        
&#039;password&#039; =&gt; &#039;myPassword1&#039;,
        
&#039;database&#039; =&gt; &#039;myDatabase1&#039;),
    
array(
        
&#039;host&#039; =&gt; &#039;myHost2&#039;,
        
&#039;username&#039; =&gt; &#039;myUsername1&#039;,
        
&#039;password&#039; =&gt; &#039;myPassword2&#039;,
        
&#039;database&#039; =&gt; &#039;myDatabase2&#039;)
    
);

    
public static function create() {
    
// Figure out which connections are open, automatically opening any connections
    
// which are failed or not yet opened but can be (re)established.
    
$cons = array();
    
for ($i = 0, $n = count(MySQLConnectionFactory::$SERVERS); $i &lt; $n; $i++) {
        
$server = MySQLConnectionFactory::$SERVERS[$i];
        
$con = mysql_pconnect($server[&#039;host&#039;], $server[&#039;username&#039;], $server[&#039;password&#039;]);
        
if (!($con === false)) {
        
if (mysql_select_db($server[&#039;database&#039;], $con) === false) {
            
echo(&#039;Could not select database: &#039; . mysql_error());
            
continue;
        
}
        
$cons[] = $con;
        
}
    
}
    
// If no servers are responding, throw an exception.
    
if (count($cons) == 0) {
        
throw new Exception
        
(&#039;Unable to connect to any database servers - last error: &#039; . mysql_error());
    
}
    
// Pick a random connection from the list of live connections.
    
$serverIdx = rand(0, count($cons)-1);
    
$con = $cons[$serverIdx];
    
// Return the connection.
    
return $con;
    
}
}
?&gt;  
&lt;a href=&quot;http://www.lightrains.com&quot; rel=&quot;nofollow&quot;&gt;Lightrains Technolabs&lt;/a&gt;
&#160;]]></description>
		<content:encoded><![CDATA[<p>Here&#8217;s a nifty little class which will load balance across multiple replicated MySQL server instances, using persistent connections, automatically removing failed MySQL servers from the pool.</p>
<p>You would ONLY use this for queries, never inserts/updates/deletes, UNLESS you had a multi-master situation where updates to any database serverautomatically replicate to the other servers (I don&#8217;t know whether that&#8217;s possible with MySQL).</p>
<p>Using this class, you get a connection to a MySQL server like this:<br />
   <br />
$con = MySQLConnectionFactory::create();</p>
<p>Here is the class (you&#8217;ll need to customize the $SERVERS array for your configuration &#8212; note that you would probably use the same username, password and database for all of the servers, just changing the host name, but you&#8217;re not forced to use the same ones):</p>
<p>&lt;? php<br />
class MySQLConnectionFactory {<br />
   <br />
static $SERVERS = array(<br />
   <br />
array(<br />
        <br />
&#8216;host&#8217; =&gt; &#8217;myHost1&#8242;,<br />
        <br />
&#8216;username&#8217; =&gt; &#8217;myUsername1&#8242;,<br />
        <br />
&#8216;password&#8217; =&gt; &#8217;myPassword1&#8242;,<br />
        <br />
&#8216;database&#8217; =&gt; &#8217;myDatabase1&#8242;),<br />
   <br />
array(<br />
        <br />
&#8216;host&#8217; =&gt; &#8217;myHost2&#8242;,<br />
        <br />
&#8216;username&#8217; =&gt; &#8217;myUsername1&#8242;,<br />
        <br />
&#8216;password&#8217; =&gt; &#8217;myPassword2&#8242;,<br />
        <br />
&#8216;database&#8217; =&gt; &#8217;myDatabase2&#8242;)<br />
   <br />
);</p>
<p>   <br />
public static function create() {<br />
    <br />
// Figure out which connections are open, automatically opening any connections<br />
   <br />
// which are failed or not yet opened but can be (re)established.<br />
    <br />
$cons = array();<br />
   <br />
for ($i = 0, $n = count(MySQLConnectionFactory::$SERVERS); $i &lt; $n; $i++) {<br />
        <br />
$server = MySQLConnectionFactory::$SERVERS[$i];<br />
        <br />
$con = mysql_pconnect($server['host'], $server['username'], $server['password']);<br />
       <br />
if (!($con === false)) {<br />
       <br />
if (mysql_select_db($server['database'], $con) === false) {<br />
           <br />
echo(&#8216;Could not select database: &#8216; . mysql_error());<br />
           <br />
continue;<br />
       <br />
}<br />
        <br />
$cons[] = $con;<br />
       <br />
}<br />
   <br />
}<br />
    <br />
// If no servers are responding, throw an exception.<br />
    <br />
if (count($cons) == 0) {<br />
       <br />
throw new Exception<br />
        <br />
(&#8216;Unable to connect to any database servers &#8211; last error: &#8216; . mysql_error());<br />
   <br />
}<br />
    <br />
// Pick a random connection from the list of live connections.<br />
    <br />
$serverIdx = rand(0, count($cons)-1);<br />
    <br />
$con = $cons[$serverIdx];<br />
    <br />
// Return the connection.<br />
    <br />
return $con;<br />
   <br />
}<br />
}<br />
?&gt;<br />
<a href="http://www.lightrains.com" rel="nofollow">Lightrains Technolabs</a><br />
&nbsp;</p>
]]></content:encoded>
	</item>
</channel>
</rss>

