Thursday, July 21, 2011

review PHP opcode with VLD

First of all, this is simply for fun.

Now let's see what VLD is. Quote from a book VLD is "a plug-in for the Zend Engine that displays all Opcodes a script uses when executed. VLD allows us to look under the hood as to what each function is doing and which system calls it's making, and most importantly it allows us to compare what may seem like a similar PHP function on the surface, lighter vs. heavier function calls"

To install:
pecl install channel://pecl.php.net/vld-0.10.1
And then add one line to your php.ini:
extension=vld.so

To show the opcodes of a script:
php -dvld.active=1 script.php

A small example:
Let's create three files called echo1.php, echo2.php, echo3.php. They all do the same thing on the surface.
echo1.php:

<?php
$name = 'henry';
echo 'hello ' . $name;

Now let's run php -dvld.active=1 echo1.php. We see the opcodes:
line    # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT                                               
          1      ASSIGN                                                 !0, 'henry'
   3     2      EXT_STMT                                                
          3      CONCAT                                      ~1     'hello+', !0
          4      ECHO                                                     ~1
   4     5    > RETURN                                               1

Pretty cool, isn't it? Now we can see PHP ASSIGN 'henry' first, then do a CONCAT, and then ECHO the result. The whole script takes 5 opcode operations. Now, move to echo2.php:
echo2.php:

<?php
$name = 'henry';
echo 'hello ' , $name;

The only difference is the echo statement in which we use comma ',' instead of period '.' . Let's see the opcodes:
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2       0  >   EXT_STMT                                                
            1      ASSIGN                                                !0, 'henry'
   3       2      EXT_STMT                                                
            3      ECHO                                                    'hello+'
            4      ECHO                                                    !0
   4       5    > RETURN                                              1

aha, now you can understand why people say using comma in echo statement is faster than using period. If we use period to concatenate a string, PHP has to do a CONCAT call and a ECHO call. In echo2.php, instead, PHP simply needs to take two ECHO operation, which is cheaper than CONCAT.  If we use more '.', we have more CONCAT operations.

Now, echo3.php:
<?php
$name = 'henry';
echo "hello $name";

The opcodes are:
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2      0  >   EXT_STMT                                                
           1      ASSIGN                                                 !0, 'henry'
   3      2      EXT_STMT                                                
           3      ADD_STRING                              ~1      'hello+'
           4      ADD_VAR                                    ~1      ~1, !0
           5      ECHO                                                      ~1
   4     6    > RETURN                                                 1

In echo3.php, we found that we need one more opcode operation than the other two. But just keep in mind that simply a few more operations doesn't necessarily mean it takes more time. Anyway, I am not a fan of micro-optimization. Say for this example, if i see someone write codes like echo1.php, i won't go to him and ask him to change for the sake of optimization. But if "using comma instead of period in echo statement" is a coding convention, then i may ask him to change for keeping coding convention.

No comments: