Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHP Performances De Cock Xavier
Who am I? <ul><li>PECL Developer  </li><ul><li>BBCode extension
Various in house extensions </li></ul><li>Swiftmailer contributor </li><ul><li>Started to work on swiftmailer for performa...
What is PHP ? <ul><li>Scripting  langage
Scripting engine </li><ul><li>Zend Engine
Extensions providing functionalities </li></ul></ul>
Zend Engine <ul><li>Memory representation of datas
Source code compilation to Opcode
Opcode Handling
Memory management </li></ul>
Meet The Zval <ul><li>Zval is the way ZE Stores values </li></ul>
Benefits <ul><li>The Zval use </li><ul><li>Copy on write
Automatic type conversion
Automatic garbage collection when ref_count is 0
As of PHP 5.3 Cyclic garbage collector </li></ul></ul>
Zval Examples <?php $a = 41 ;  /* Context (&quot;a&quot; => Zval_1);  * Zval_1 {ref_count:1, value:41, type:LONG}; */ $b  ...
Don't try to outsmart ZE <ul><li>Working by reference will usually make you waste memory as it can trigger more easily the...
Zend Op <ul><li>Opcode is the “machine langage” of ZE
What's in a zend_op </li><ul><li>OpCode
Op1
Op2
Upcoming SlideShare
Loading in …5
×

PHP Performance SfLive 2010

12,322 views

Published on

Php performance presentation on symfony live

Published in: Technology
  • Be the first to comment

PHP Performance SfLive 2010

  1. PHP Performances De Cock Xavier
  2. Who am I? <ul><li>PECL Developer </li><ul><li>BBCode extension
  3. Various in house extensions </li></ul><li>Swiftmailer contributor </li><ul><li>Started to work on swiftmailer for performance issues. </li></ul></ul>
  4. What is PHP ? <ul><li>Scripting langage
  5. Scripting engine </li><ul><li>Zend Engine
  6. Extensions providing functionalities </li></ul></ul>
  7. Zend Engine <ul><li>Memory representation of datas
  8. Source code compilation to Opcode
  9. Opcode Handling
  10. Memory management </li></ul>
  11. Meet The Zval <ul><li>Zval is the way ZE Stores values </li></ul>
  12. Benefits <ul><li>The Zval use </li><ul><li>Copy on write
  13. Automatic type conversion
  14. Automatic garbage collection when ref_count is 0
  15. As of PHP 5.3 Cyclic garbage collector </li></ul></ul>
  16. Zval Examples <?php $a = 41 ; /* Context (&quot;a&quot; => Zval_1); * Zval_1 {ref_count:1, value:41, type:LONG}; */ $b = $a ; /* Context (&quot;a&quot; => Zval_1, &quot;b&quot; => Zval_1); * Zval_1 {ref_count:2, value:41, type:LONG}; */ $b ++ ; /* Context (&quot;a&quot;=> Zval_1, &quot;b&quot; => Zval_2); * Zval_1 {ref_count:1, value:41, type:LONG}; * Zval_2 {ref_count:1, value:42, type:LONG}; */ $b .= &quot;, The answer ...&quot; ; /* Context (&quot;a&quot;=> Zval_1, &quot;b&quot; => Zval_3); * Zval_1 {ref_count:1, value:41, type:LONG}; * Zval_2 {ref_count:0, value:42, type:LONG}; // Freed * Zval_3 {ref_count:1, value:&quot;42, The answer ...&quot;, type:STRING}; */
  17. Don't try to outsmart ZE <ul><li>Working by reference will usually make you waste memory as it can trigger more easily the copy on write </li></ul>< ?php $a = 1 ; /* Zval {val:1; ref_count:1; is_ref:f} */ $b = & $a ; /* Zval {val:1; ref_count:2; is_ref: t } */ print ( $b ); /* This is a pass by value function, so, * what's send to print is : * Zval2 {val:1 ref_count:1; is_ref:f } */
  18. Zend Op <ul><li>Opcode is the “machine langage” of ZE
  19. What's in a zend_op </li><ul><li>OpCode
  20. Op1
  21. Op2
  22. Metas (line n°, handler, result, ...) </li></ul></ul>
  23. Opcode examples <?php echo &quot;Hello&quot;, &quot; &quot;, &quot;World&quot;; filename: /home/xavier/- function name: (null) number of ops: 5 compiled vars: none line # op operands --------------------------------------------- 2 0 ECHO OP1[ 'Hello' ] 1 ECHO OP1[ ' ' ] 2 ECHO OP1[ 'World' ] 4 3 RETURN OP1[ 1 ] 4* ZEND_HANDLE_EXCEPTION
  24. Opcode examples <?php echo &quot;Hello&quot;.&quot; &quot;.&quot;World&quot;; filename: /home/xavier/- function name: (null) number of ops: 5 compiled vars: none line # op return operands --------------------------------------- 2 0 CONCAT RES[ ~0 ] OP1[ 'Hello' ] OP2[ '+' ] 1 CONCAT RES[ ~1 ] OP1[ ~0 ] OP2[ 'World' ] 2 ECHO OP1[ ~1 ] 3 3 RETURN OP1[ 1 ] 4* ZEND_HANDLE_EXCEPTION
  25. Hash Tables <ul><li>Everythings basically stays in an hash table </li><ul><li>Symbol Tables (Local / global Variables)
  26. Arrays
  27. Object Properties
  28. Ini Directives, included Files
  29. Classes, Functions, Constants </li></ul></ul>
  30. Hash Tables <ul><li>Pros: </li><ul><li>2 quick access patterns </li><ul><li>Get value by key
  31. Table Traversal nest / previous item </li></ul><li>Count is a fast operation </li></ul><li>Cons: </li><ul><li>Not able to browse by value </li></ul></ul>
  32. Garbage collector <ul><li>PHP 5.3 includes a Garbage collector that break reference cycle.
  33. PHP 5.2 does not include a GC </li><ul><li>Avoid creating cycles
  34. Break them before unset
  35. Try to keep in mind what can hold ref </li></ul><li>Keep in mind what handle ref: </li><ul><li>Closures, Callback, Ressources, ... </li></ul></ul>
  36. SwiftMailer Examples Implementation 1 foreach ( unpack ('C*' , $bytes ) as $byte ) // Convert String to int array { $this -> _array [] = pack ('C' , $byte ); // Function Call in tight loop } filename: /home/xavier/Bureau/php-5.3.1/ext/- function name: (null) number of ops: 17 compiled vars: !0 = $bytes, !1 = $byte line # op return operands ----------------------------------------------- 2 0 SEND_VAL OP1[ 'C*' ] 1 SEND_VAR OP1[ !0 ] 2 DO_FCALL OP1[ 'unpack' ] 3 FE_RESET RES[ $1 ] OP1[ $0 ] OP2[ ->14 ] 4 FE_FETCH RES[ $2 ] OP1[ $1 ] OP2[ ->14 ] 5 ZEND_OP_DATA RES[ UNUSED ] OP1[ UNUSED ] OP2[ UNUSED ] 6 ASSIGN OP1[ !1 ] OP2[ $2 ] 4 7 SEND_VAL OP1[ 'C' ] 8 SEND_VAR OP1[ !1 ] 9 DO_FCALL OP1[ 'pack' ] 10 FETCH_OBJ_W RES[ $4 ] OP1[ UNUSED ] OP2[ '_array' ] 11 ZEND_ASSIGN_DIM OP1[ $4 ] OP2[ UNUSED ] 12 ZEND_OP_DATA RES[ UNUSED ] OP1[ $6 ] OP2[ $7 ] 5 13 JMP OP1[ ->4 ] 14 SWITCH_FREE RES[ UNUSED ] OP1[ $1 ] 6 15 RETURN OP1[ 1 ] 16* ZEND_HANDLE_EXCEPTION
  37. SwiftMailer Examples Implementation 2 $to_add = str_split ( $bytes ); // Convert string to char array /* add the array as first arg of the function */ array_unshift ( $to_add , & $this -> _array ); // Will trigger E_STRICT /* Push all elements in one function call and get the count */ $this -> _arraySize = call_user_func_array ('array_push' , $to_add ); compiled vars: !0 = $to_add, !1 = $bytes line # op return operands -------------------------------------------------------------------------- 2 0 SEND_VAR OP1[ !1 ] 1 DO_FCALL OP1[ 'str_split' ] 2 ASSIGN OP1[ !0 ] OP2[ $0 ] 4 3 SEND_REF RES[ UNUSED ] OP1[ !0 ] OP2[ UNUSED ] 4 FETCH_OBJ_W RES[ $2 ] OP1[ UNUSED ] OP2[ '_array' ] 5 SEND_REF RES[ UNUSED ] OP1[ $2 ] OP2[ UNUSED ] 6 DO_FCALL OP1[ 'array_unshift' ] 6 7 SEND_VAL OP1[ 'array_push' ] 8 SEND_VAR OP1[ !0 ] 9 DO_FCALL OP1[ 'call_user_func_array' ] 10 ZEND_ASSIGN_OBJ OP1[ UNUSED ] OP2[ '_arraySize' ] 11 ZEND_OP_DATA RES[ UNUSED ] OP1[ $5 ] OP2[ UNUSED ] 7 12 RETURN OP1[ 1 ] 13* ZEND_HANDLE_EXCEPTION
  38. SwiftMailer Examples Implementation 3 $to_add = str_split ( $bytes ); // Convert string to char array /* Calls array Merge */ /* Array merge works by copying the first array element By element, then the second, third, … The speed decreases with the number of items in each array */ $this -> _array = array_merge ( $this -> _array , $to_add ); $this -> _arraySize = count ( $this -> _array ); compiled vars: !0 = $to_add, !1 = $bytes line # op return operands ------------------------------------------------------------------------------- 2 0 SEND_VAR OP1[ !1 ] 1 DO_FCALL OP1[ 'str_split' ] 2 ASSIGN OP1[ !0 ] OP2[ $0 ] 7 3 FETCH_OBJ_R RES[ $3 ] OP1[ UNUSED ] OP2[ '_array' ] 4 SEND_VAR OP1[ $3 ] 5 SEND_VAR OP1[ !0 ] 6 DO_FCALL OP1[ 'array_merge' ] 7 ZEND_ASSIGN_OBJ OP1[ UNUSED ] OP2[ '_array' ] 8 ZEND_OP_DATA RES[ UNUSED ] OP1[ $4 ] OP2[ UNUSED ] 8 9 FETCH_OBJ_R RES[ $6 ] OP1[ UNUSED ] OP2[ '_array' ] 10 SEND_VAR OP1[ $6 ] 11 DO_FCALL OP1[ 'count' ] 12 ZEND_ASSIGN_OBJ OP1[ UNUSED ] OP2[ '_arraySize' ] 13 ZEND_OP_DATA RES[ UNUSED ] OP1[ $7 ] OP2[ UNUSED ] 10 14 RETURN OP1[ 1 ] 15* ZEND_HANDLE_EXCEPTION
  39. SwiftMailer Examples Implementation 4 $to_add = str_split ( $bytes ); foreach ( $to_add as $value ) { $this -> _array [] = $value ; } $this -> _arraySize = count ( $this -> _array ); compiled vars: !0 = $to_add, !1 = $bytes, !2 = $value line # op return operands -------------------------------------------------------------------------- 1 0 SEND_VAR OP1[ !1 ] 1 DO_FCALL OP1[ 'str_split' ] 2 ASSIGN OP1[ !0 ] OP2[ $0 ] 2 3 FE_RESET RES[ $2 ] OP1[ !0 ] OP2[ ->11 ] 4 FE_FETCH RES[ $3 ] OP1[ $2 ] OP2[ ->11 ] 5 ZEND_OP_DATA RES[ UNUSED ] OP1[ UNUSED ] OP2[ UNUSED ] 6 ASSIGN OP1[ !2 ] OP2[ $3 ] 3 7 FETCH_OBJ_W RES[ $5 ] OP1[ UNUSED ] OP2[ '_array' ] 8 ZEND_ASSIGN_DIM OP1[ $5 ] OP2[ UNUSED ] 9 ZEND_OP_DATA RES[ UNUSED ] OP1[ !2 ] OP2[ $7 ] 4 10 JMP OP1[ ->4 ] 11 SWITCH_FREE RES[ UNUSED ] OP1[ $2 ] 5 12 FETCH_OBJ_R RES[ $9 ] OP1[ UNUSED ] OP2[ '_array' ] 13 SEND_VAR OP1[ $9 ] 14 DO_FCALL OP1[ 'count' ] 15 ZEND_ASSIGN_OBJ OP1[ UNUSED ] OP2[ '_arraySize' ] 16 ZEND_OP_DATA RES[ UNUSED ] OP1[ $10 ] OP2[ UNUSED ] 6 17 RETURN OP1[ 1 ] 18* ZEND_HANDLE_EXCEPTION
  40. How to optimize? <ul><li>Be efficient: </li><ul><li>Optimize tight loops, one line functions
  41. Highly covered source code (profile your app) </li></ul><li>Use tools </li><ul><li>Vulcan Logic Dumper (pecl vld)
  42. Xdebug / Zend Debug – Profilers </li></ul></ul>
  43. Other ways <ul><li>Use built-in functions (except array_* and in_array)
  44. Use Opcode Caching : APC, eAccelerator, XCache, Zend Server, …
  45. Use data Caching : Memcached,
  46. Optimize your SQL
  47. Access your data by batches
  48. Create PHP Extension
  49. Use other implementations : Facebook's HipHop, phc, Quercus, RoadSend PHP </li></ul>
  50. Questions? Thanks for listening

×