In-depth understanding of PHP opcode caching principles

Source: Internet
Author: User
Tags add numbers apc php source code vars zend

What is a opcode cache?

When the interpreter finishes parsing the script code, it generates intermediate code that can be run directly, also known as the opcode (Operate code,opcode). The goal of the Opcode cache is to avoid duplication of compilation and reduce CPU and memory overhead. If the performance bottleneck for dynamic content is not CPU and memory, but I/O operations, such as disk I/O overhead from database queries, the performance gains of the opcode cache are very limited. But since the opcode cache can bring down CPU and memory overhead, this is always a good thing.

Modern opcode buffers (optimizer+,apc2.0+, others) are stored using shared memory and can be executed directly from the file without the "deserialization" code before execution. This leads to significant performance acceleration, which typically reduces the overall server's memory consumption and has few drawbacks.

Why use the opcode cache?

This has to be said from the life cycle of the PHP code, which takes five steps when requesting a PHP script, as shown in:

The Zend engine must read files from the file system, scan its dictionaries and expressions, parse files, create computer code to execute (called opcode), and finally execute opcode. Each time the PHP script will execute the above steps, if the PHP source code does not change, then opcode will not change, obviously there is no need to re-generate opcode every time, combined with the ubiquitous caching mechanism in the web, we can cache opcode, It is not faster to access the cached opcode directly later, and the flowchart after enabling opcode caching is as follows:

are there those php opcode cache plugins?

Optimizer+ (optimizer+ in mid-March 2013 opcache,php 5.5 episode Opcache, the others will not disappear? ), Eaccelerator, XCache, APC ...

PHP opcode principle

OpCode is a PHP script-compiled intermediate language, like Java's bytecode, or. NET MSL, for example, you write down the following PHP code:

    1. <?php
    2. echo "Hello World";
    3. $a = 1 + 1;
    4. echo $a;
    5. ?>

PHP executes this code in the following 4 steps (to be exact, it should be PHP's language engine Zend)

    1. Scanning (lexing), converting the PHP code to a language fragment (Tokens)
    2. parsing, converting tokens into simple and meaningful expressions
    3. compilation, compile the expression into Opocdes
    4. Execution, execute opcodes sequentially, one at a time, thus realizing the function of PHP script

Aside: Now some caches such as APC, can make PHP cache opcodes, so that every time there is a request, there is no need to repeat the previous 3 steps, so that can greatly improve the speed of PHP execution.

Then what is lexing? The students who have learned the principles of compiling should have some knowledge of the lexical analysis steps in the compiling principle, Lex is a basis table for lexical analysis. ZEND/ZEND_LANGUAGE_SCANNER.C will perform lexical analysis based on the PHP code entered by the ZEND/ZEND_LANGUAGE_SCANNER.L (lex file) to get a "word", PHP4.2 began to provide a function called Token_get_all, this function can be said a section of PHP code scanning into tokens;

If we use this function to process the PHP code we mentioned at the beginning, we will get the following result:

  1. Array
  2. (
  3. [0] = = Array
  4. (
  5. [0] = 367
  6. [1] = = Array
  7. (
  8. [0] = 316
  9. [1] = echo
  10. )
  11. [2] = = Array
  12. (
  13. [0] = 370
  14. [1] = =
  15. )
  16. [3] = = Array
  17. (
  18. [0] = 315
  19. [1] = "Hello World"
  20. )
  21. [4] = =;
  22. [5] = = Array
  23. (
  24. [0] = 370
  25. [1] = =
  26. )
  27. [6] = =
  28. [7] = = Array
  29. (
  30. [0] = 370
  31. [1] = =
  32. )
  33. [8] = = Array
  34. (
  35. [0] = 305
  36. [1] = 1
  37. )
  38. [9] = = Array
  39. (
  40. [0] = 370
  41. [1] = =
  42. )
  43. [Ten] = +
  44. [one] = = Array
  45. (
  46. [0] = 370
  47. [1] = =
  48. )
  49. [+] = Array
  50. (
  51. [0] = 305
  52. [1] = 1
  53. )
  54. [+] =;
  55. [+] = Array
  56. (
  57. [0] = 370
  58. [1] = =
  59. )
  60. [+] = Array
  61. (
  62. [0] = 316
  63. [1] = echo
  64. )
  65. [+] = Array
  66. (
  67. [0] = 370
  68. [1] = =
  69. )
  70. [+] =;
  71. )

Analysis of the return result we can find that the source of strings, characters, spaces, will be returned as is. Each character in the source code appears in the appropriate order. And, other such as tags, operators, statements, will be converted to a two-part Array:token ID (that is, in the Zend internal change Token of the corresponding code, such as, t_echo,t_string), and the source of the original content.

Next, is the parsing stage, parsing first discards more spaces in the tokens array, and then converts the remaining tokens to a simple expression of one

    1. echo a constant string
    2. Add numbers together
    3. Store the result of the prior expression to a variable
    4. echo a variable

Then change the compilation stage, it will tokens compiled into a op_array, each op_arrayd contains the following 5 parts:

    1. The identification of the opcode number, indicating the type of operation for each op_array, such as Add, echo
    2. Results Store opcode results
    3. Operand 1 to opcode operand
    4. Number of Operations 2
    5. Extended value 1 shaping to differentiate the overloaded operator

For example, our PHP code will be parsing into:

    1. * zend_echo ' Hello world '
    2. * Zend_add ~0 1 1
    3. * Zend_assign!0 ~0
    4. * Zend_echo!0

You might ask, where is our $ A?

This introduces the operands, each of which consists of the following two parts:

    1. Op_type: For Is_const, Is_tmp_var, Is_var, is_unused, or IS_CV b)
    2. U, a consortium, holds the value (const) or Lvalue (Var) of this operand in different types, depending on the op_type.

And for Var, every Var is different.

Is_tmp_var, as the name implies, this is a temporary variable, save some Op_array results, so that the next op_array to use, this operand of u holds a pointer to the variable table of a handle (integer), this operand is generally used to start, such as ~0, A temporary variable that represents the unknown number No. 0 of the variable table

Is_var This is our general sense of the variable, they start with a $ expression

IS_CV says ZE2.1/ PHP5.1 later compiler uses a cache mechanism, this variable holds the address of the variable referenced by it, when a variable is referenced for the first time, it will be CV up, the reference to this variable will not need to find the active symbol table again, CV variable to! The beginning indicates.

So it seems that our $ A is optimized to 0.

Reference: http://www.laruence.com/2008/06/18/221.html

In-depth understanding of PHP opcode caching principles

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.