PHP itself is written in C, as are Flex and Bison, the programs that PHP uses to generate its internal lexer and parser. The process of executing PHP code works by matching various parts of code against pre-defined lists of acceptable grammar. For example:
T_IF T_LEFTBRACK T_CONDITION T_RIGHTBRACK T_LEFTBRACE T_STATEMENT T_RIGHTBRACE
In that piece of pseudo-grammar, T stands for "Type". It will match a statement that starts with "if", then an opening bracket, followed by any boolean condition, followed by a close bracket, then an opening brace, a statement, then a closing brace. Sound familiar? PHP uses the same sort of rules -- although on a much more complicated level -- to parse your code. Of course, PHP has hundreds of such rules, and when it matches them it calls appropriate internal C functions to handle the statement. For example, take a look at this rule direct from the PHP source code:
T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
The Zend Engine will, amongst other things, call "fetch_array_begin(&$$, &$2, &$4 TSRMLS_CC)", which uses items 2 and 4 of the rule (T_STRING_VARNAME and expr) to read and return an array item. This means that no matter how fast your PHP code is, it still has to be interpreted then executed as normal C code. PHP scripts are not compiled to native machine code at any point, so there is never any chance of it out-performing C, or generally even coming close to the performance of C.
So, the way to make your PHP code faster is to replace chunks of it with pure, compiled C. In PHP, this can be done in three ways: writing your own module, editing the PHP source code, or editing the Zend Engine. Writing a module for PHP is the accepted way to add functionality, and there are many modules available in PHP to do all sorts of tasks. However, modules are the slowest way to add functionality, particularly if calls to dl() are required to dynamically load the module each time a script needs it.
Writing functions directly into the PHP source code is faster than using modules, but only really possible if you are working on your own server. Finally, writing functions directly into the Zend Engine provides the biggest performance boost, but basically confines your script to your own machine - not many would be willing to patch their Zend Engine code to try out your code! There is actually a surprising boost for shifting code into the Zend Engine - when Andrei Zmievski converted strlen() into a Zend Engine operation as opposed to a function, he reported a 25% speed boost.
With such a big gain to be offered, you are probably thinking everything should be put directly into the Zend Engine. However, it is important to realise that there is a big trade-off between speed and manageability, and generally modules come out top because they operate more than fast enough for most needs.
If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!
Next chapter: Before we begin >>
Previous chapter: Why write your own extension?
Home: Table of Contents
Copyright ©2015 Paul Hudson. Follow me: @twostraws.