<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
    
    <title> Rasmus' Toys Page</title>
    <link>http://toys.lerdorf.com/</link>
    <description></description>
    <dc:language>en</dc:language>
    <admin:errorReportsTo rdf:resource="mailto:" />
    <generator>Serendipity 1.6-alpha1 - http://www.s9y.org/</generator>
    <pubDate>Tue, 16 Feb 2010 16:57:44 GMT</pubDate>

    <image>
        <url>http://toys.lerdorf.com/templates/default/img/s9y_banner_small.png</url>
        <title>RSS:  Rasmus' Toys Page - </title>
        <link>http://toys.lerdorf.com/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>A quick look at XHP</title>
    <link>http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html</link>
    
    <comments>http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html#comments</comments>
    <wfw:comment>http://toys.lerdorf.com/wfwcomment.php?cid=54</wfw:comment>

    <slash:comments>9</slash:comments>
    <wfw:commentRss>http://toys.lerdorf.com/rss.php?version=2.0&amp;type=comments&amp;cid=54</wfw:commentRss>
    

    <author>rasmus@lerdorf.com (Rasmus)</author>
    <content:encoded>
    Facebook released a new PHP extension today that supports inlining XML.  This is a feature known as &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb384832.aspx&quot;&gt;XML Literals in Visual Basic&lt;/a&gt;.  Go read their description here:
&lt;a href=&quot;http://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919&quot;&gt;http://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919&lt;/a&gt;
&lt;br /&gt;
It adds an extra parsing step which maps inlined XML elements to PHP classes.  These classes are &lt;a href=&quot;http://github.com/facebook/xhp/blob/master/php-lib/core.php&quot;&gt;core.php&lt;/a&gt; and &lt;a href=&quot;http://github.com/facebook/xhp/blob/master/php-lib/html.php&quot;&gt;html.php&lt;/a&gt; which covers all the main HTML elements.  The syntax of those class definitions is a bit odd.  That oddness is explained in the &lt;a href=&quot;http://wiki.github.com/facebook/xhp/how-it-works&quot;&gt;How It Works&lt;/a&gt; document.
&lt;br /&gt;&lt;br /&gt;
Essentially, it lets you turn:

&lt;pre style=&quot;background: #ddd; border: 1px solid #000; padding: 5px; line-height:1em; width:60%;&quot;&gt;
&amp;lt;?php
if ($_POST[&#039;name&#039;]) {
    echo &quot;&amp;lt;span&amp;gt;Hello, {$_POST[&#039;name&#039;]}.&amp;lt;/span&amp;gt;&quot;;
} else {
?&amp;gt;
    &amp;lt;form method=&quot;post&quot;&amp;gt;
    What is your name?&amp;lt;br&amp;gt;
    &amp;lt;input type=&quot;text&quot; name=&quot;name&quot;&amp;gt;
    &amp;lt;input type=&quot;submit&quot;&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt?php
}
&lt;/pre&gt;

into:

&lt;pre style=&quot;background: #ddd; border: 1px solid #000; padding: 5px; line-height:1em; width: 60%;&quot;&gt;
&amp;lt;?php
require &#039;./core.php&#039;;
require &#039;./html.php&#039;;
if ($_POST[&#039;name&#039;]) {
  echo &amp;lt;span&amp;gt;Hello, {$_POST[&#039;name&#039;]}.&amp;lt;/span&amp;gt;;
} else {
  echo
    &amp;lt;form method=&quot;post&quot;&amp;gt;
      What is your name?&amp;lt;br /&amp;gt;
      &amp;lt;input type=&quot;text&quot; name=&quot;name&quot; /&amp;gt;
      &amp;lt;input type=&quot;submit&quot; /&amp;gt;
    &amp;lt;/form&amp;gt;;
}
&lt;/pre&gt;

The main interest, at least to me, is that because PHP now understands the XML it is outputting, filtering can be done in a context-sensitive manner.  The &lt;a href=&quot;http://php.net/filter&quot;&gt;input filtering&lt;/a&gt; built into PHP can not know which context a string is going to be used in.  If you use a string inside an on-handler or a style attribute, for example, you need radically different filtering from it being used as regular XML PCDATA in the html body.  Some will say this form is more readable as well, but that isn&#039;t something that concerns me very much.
&lt;br /&gt;&lt;br /&gt;
The real question here is what is this runtime xml validation going to cost you.  I have given talks in the past where I have used &quot;class br extends html { ... }&quot; as a classic example of something you should never do.  A br tag is just a br tag.  When you need one, stick a &amp;lt;br&amp;gt; in your page, don&#039;t instantiate a class and call a render() method.  So, when I looked at &lt;a href=&quot;http://github.com/facebook/xhp/blob/master/php-lib/html.php&quot;&gt;html.php&lt;/a&gt; and saw:

&lt;pre style=&quot;background: #ddd; border: 1px solid #000; padding: 5px; line-height:1em; width:60%;&quot;&gt;
class :br extends :xhp:html-singleton {
  category %flow, %phrase;
  protected $tagName = &#039;br&#039;;
}
&lt;/pre&gt;

I got a bit skeptical.  Another thing I have been known to tell people is, &quot;Friend don&#039;t let friends use Singletons.&quot;  Which isn&#039;t something I came up with.  Someone, a friend, I guess, told me that years ago.  Ok ok, as Marcel points out in the comments, this isn&#039;t a real singleton, just in name.    
&lt;br /&gt;&lt;br /&gt;
The &amp;quot;singleton&amp;quot; looks like this:

&lt;pre style=&quot;background: #ddd; border: 1px solid #000; padding: 5px; line-height:1em; width:60%;&quot;&gt;
abstract class :xhp:html-singleton extends :xhp:html-element {
  children empty;
 
  protected function stringify() {
    return $this-&gt;renderBaseAttrs() . &#039; /&gt;&#039;;
  }
}
&lt;/pre&gt;

which extends html-element which in turn extends primitive.  You can go read all the code for those yourself.
&lt;br /&gt;&lt;br /&gt;
Note that to build XHP you will need flex 2.5.35 which most distros won&#039;t have installed by default.  Grab the &lt;a href=&quot;http://prdownloads.sourceforge.net/flex/flex-2.5.35.tar.gz?download&quot;&gt;flex tarball&lt;/a&gt; and ./configure &amp;&amp;amp; make install it.  Then you are ready to go.
&lt;br /&gt;&lt;br /&gt;
I pointed &lt;a href=&quot;http://www.joedog.org/index/siege-home&quot;&gt;Siege&lt;/a&gt; at my rather underpowered AS1410 SU2300 with the above trivial form examples.  The plain PHP one and the XHP version.  Ran each one 5 times benchmarking for 30s each time.  The plain PHP one averaged around 1300 requests/sec.  Here is a representative sample:

&lt;pre style=&quot;background: #000; border: 1px solid #fff; padding: 5px; line-height:1em; color:#fff; width:60%;&quot;&gt;
acer:~&gt; siege -c 3 -b -t30s http://xhp.localhost/1.php
** SIEGE 2.68
** Preparing 3 concurrent users for battle.
The server is now under siege...
Lifting the server siege...      done.
Transactions:		       38239 hits
Availability:		      100.00 %
Elapsed time:		       29.60 secs
Data transferred:	        3.97 MB
Response time:		        0.00 secs
Transaction rate:	     1291.86 trans/sec
Throughput:		        0.13 MB/sec
Concurrency:		        2.93
Successful transactions:       38239
Failed transactions:	           0
Longest transaction:	        0.05
Shortest transaction:	        0.00
&lt;/pre&gt;

And the XHP version:

&lt;pre style=&quot;background: #000; border: 1px solid #fff; padding: 5px; line-height:1em; color:#fff; width:60%;&quot;&gt;
Transactions:		         868 hits
Availability:		      100.00 %
Elapsed time:		       29.28 secs
Data transferred:	        0.08 MB
Response time:		        0.10 secs
Transaction rate:	       29.64 trans/sec
Throughput:		        0.00 MB/sec
Concurrency:		        2.99
Successful transactions:         868
Failed transactions:	           0
Longest transaction:	        0.21
Shortest transaction:	        0.05
&lt;/pre&gt;

So, a drop from 1300 to around 30 requests per second and latency from less than 10ms to 100ms.  Running XHP on plain PHP is definitely out of the question.  But, knowing that Facebook uses APC heavily and looking through the code (see the MINIT function in &lt;a href=&quot;http://github.com/facebook/xhp/blob/master/ext.cpp&quot;&gt;ext.cpp&lt;/a&gt;) we can see that it should play nicely with APC.  So, re-running our PHP version of the form, now with APC enabled, that goes from 1300 to around 1460 requests per second, and no measurable latency:

&lt;pre style=&quot;background: #000; border: 1px solid #fff; padding: 5px; line-height:1em; color:#fff; width:60%;&quot;&gt;
Transactions:		       43773 hits
Availability:		      100.00 %
Elapsed time:		       29.88 secs
Data transferred:	        4.55 MB
Response time:		        0.00 secs
Transaction rate:	     1464.96 trans/sec
Throughput:		        0.15 MB/sec
Concurrency:		        2.93
Successful transactions:       43773
Failed transactions:	           0
Longest transaction:	        0.07
Shortest transaction:	        0.00
&lt;/pre&gt;

The XHP version of the form now with APC enabled:

&lt;pre style=&quot;background: #000; border: 1px solid #fff; padding: 5px; line-height:1em; color:#fff; width:60%;&quot;&gt;
Transactions:		        9707 hits
Availability:		      100.00 %
Elapsed time:		       29.45 secs
Data transferred:	        0.94 MB
Response time:		        0.01 secs
Transaction rate:	      329.61 trans/sec
Throughput:		        0.03 MB/sec
Concurrency:		        2.97
Successful transactions:        9707
Failed transactions:	           0
Longest transaction:	        0.21
Shortest transaction:	        0.00
&lt;/pre&gt;

Much better.  But it is still around a 75% performance drop from 1460 to 330 and a ~10ms latency penalty.  And yes, I did have a default filter enabled for these tests, so there was basic XSS filtering in place for the naked $_POST[&#039;name&#039;] variable in the plain PHP version.  Of course, the default filtering would likely fail if the user data was used in a different context.  And this 75% is obviously going to depend on what else is going on during the request.  If you are spending most of your time calculating a fractal or waiting on MySQL, you may not notice XHP very much at all.
&lt;br /&gt;&lt;br /&gt;
The bulk of the time is spent in all the tag to class interaction.  If the core.php and html.php code was all baked into the XHP extension, it would be a lot quicker, of course.  So, when you combine XHP with HipHop PHP you can start to imagine that the performance penalty would be a lot less than 75% and it becomes a viable approach.  Of course, this also means that if you are unable to run HipHop you probably want to think a bit and run some tests before adopting this.  If you are already doing some sort of external templating, XHP could very well be a faster approach.

 &lt;br /&gt;&lt;a href=&quot;http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html#extended&quot;&gt;Continue reading &quot;A quick look at XHP&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Tue, 09 Feb 2010 21:22:35 -0800</pubDate>
    <guid isPermaLink="false">http://toys.lerdorf.com/archives/54-guid.html</guid>
    
</item>
<item>
    <title>HipHop PHP - Nifty Trick?</title>
    <link>http://toys.lerdorf.com/archives/53-HipHop-PHP-Nifty-Trick.html</link>
    
    <comments>http://toys.lerdorf.com/archives/53-HipHop-PHP-Nifty-Trick.html#comments</comments>
    <wfw:comment>http://toys.lerdorf.com/wfwcomment.php?cid=53</wfw:comment>

    <slash:comments>12</slash:comments>
    <wfw:commentRss>http://toys.lerdorf.com/rss.php?version=2.0&amp;type=comments&amp;cid=53</wfw:commentRss>
    

    <author>rasmus@lerdorf.com (Rasmus)</author>
    <content:encoded>
    In a response to a question from ReadWriteWeb, among other things, I wrote:

&lt;blockquote&gt;
My main worry here is that people think this is some kind of magic
bullet that will solve their site performance problems.  Generating C++
code from PHP code is a nifty trick and people seem to have gotten quite
excited about it.  I&#039;d love to see those same people get excited about
basic profiling and identifying the most costly areas of an application.
Speeding up one of the faster parts of your system isn&#039;t going to give
you anywhere near as much of a benefit as speeding up, or eliminating,
one of the slower parts of your overall system.
&lt;/blockquote&gt;

The &quot;nifty trick&quot; part of that seems to have become the story, and them 
injecting a &quot;just&quot; in front it of it makes it sound more derogatory.  Anyone
who knows me knows that I am a big fan of nifty tricks that solve the problem.
When I first heard about the Facebook effort I was assuming they were writing
a JIT based on LLVM V8 or something along those lines.  Writing a good JIT is
hard.  Doing static code analysis and generating compilable C++ from it is
indeed a nifty trick.  It&#039;s not &quot;just&quot; a nifty trick, it is a cool trick that takes
advantage of a number of characteristics of PHP.  The main one being that
you can&#039;t overload PHP functions.  strlen() is always strlen, for example.  In
Python, this would be harder because you can overload everything.
&lt;br /&gt;&lt;br /&gt;
I also noted that most sites on the Web have a lot of lower hanging fruit that
would provide a much bigger performance improvement, if fixed, than doubling
the speed of the PHP execution phase.  The ReadWriteWeb site, for example, 
needs 160 separate HTTP requests and 41 distinct DNS lookups to load the
front page.  And once you get beyond the frontend inefficiencies you usually
find Database issues, inefficient system call issues and general architecture
problems that again aren&#039;t solved by speeding up PHP execution.
&lt;br /&gt;&lt;br /&gt;
If you have done your homework and find that your web servers are cpu-bound,
you are already using an opcode cache like &lt;a href=&quot;http://pecl.php.net/apc&quot;&gt;APC&lt;/a&gt; 
and your &lt;a href=&quot;http://valgrind.org/info/tools.html#callgrind&quot;&gt;Callgrind&lt;/a&gt; callgraph
shows you that the PHP executor is a significant bottleneck, then HipHop PHP is
definitely something you should be looking at. 
    </content:encoded>

    <pubDate>Thu, 04 Feb 2010 10:50:37 -0800</pubDate>
    <guid isPermaLink="false">http://toys.lerdorf.com/archives/53-guid.html</guid>
    
</item>

</channel>
</rss>