Home  >  Article  >  Backend Development  >  An in-depth discussion of PHP performance_PHP Tutorial

An in-depth discussion of PHP performance_PHP Tutorial

WBOY
WBOYOriginal
2016-07-13 10:38:39878browse

1.Origin

Regarding PHP, many people's intuitive feeling is that PHP is a flexible scripting language with rich library classes, easy to use, safe, and very suitable for WEB development, but its performance is low. Is the performance of PHP really as bad as everyone feels? This article focuses on such a topic. In-depth analysis of PHP performance issues from source code, application scenarios, benchmark performance, comparative analysis and other aspects, and speak through real data.

2. Analyze PHP performance from the principle

Analyze the performance of PHP from the principle, mainly from the following aspects: memory management, variables, functions, and operating mechanism.

2.1 Memory Management

Similar to Nginx's memory management method, PHP is also based on a memory pool internally, and introduces the life cycle concept of the memory pool. In terms of memory pools, PHP manages all memory-related operations of PHP scripts and extensions. Different implementation methods and optimizations are used to manage large memory and small memory. For details, please refer to the following document: https://wiki.php.net/internals/zend_mm. During the life cycle of memory allocation and recycling, PHP uses an initialization application + dynamic expansion + memory identification recycling mechanism, and directly re-masks the memory pool after each request.

2.2 Variables

As we all know, PHP is a weak variable type language, so within PHP, all PHP variables correspond to a type Zval, which is specifically defined as follows:

大话PHP之性能

Figure 1 PHP variable

In terms of variables, PHP has done a lot of optimization work, such as Reference counting and copy on writer mechanisms. This can ensure the optimization of memory usage and reduce the number of memory copies (please refer to http://blog.xiuwz.com/2011/11/09 /php-using-internal-zval/). In terms of arrays, PHP uses an efficient hashtable internally to implement it.

2.3 Function

Within PHP, all PHP functions are converted into an internal function pointer. For example, the expanding function


  1. 		ZEND_FUNCTION ( my_function );//类似function my_function(){}  

After internal expansion, it will be a function


  1. 		void zif_my_function ( INTERNAL_FUNCTION_PARAMETERS );  
  2. void zif_my_function(
  3. int ht,
  4. zval * return_value,
  5. zval * this_ptr,
  6. int return_value_used,
  7. zend_executor_globals * executor_globals
  8. );

From this perspective, PHP functions also correspond to a function pointer internally.

2.4 Operating mechanism

When talking about PHP performance, many people will say "C/C++ is compiled, JAVA is semi-compiled, and PHP is interpreted." In other words, PHP is dynamically parsed first and then the code is run, so from this perspective, PHP performance must be very poor.

Indeed, output from running a PHP script is indeed a process of dynamic parsing and then code running. Specifically, the operating mechanism of the PHP script is as shown in the figure below:

大话PHP之性能

Figure 2 PHP operating mechanism

The running phase of PHP is also divided into three phases:

  • Parse. Syntax analysis stage.
  • Compile. Compile and output opcode intermediate code.
  • Execute. Run, run dynamically for output.

Therefore, within PHP, there is also a compilation process. And based on this, a large number of opcode cache tools have been produced, such as apc, eacc, xcache, etc. These opcode caches are basically standard in production environments. Based on opcode cache, it can achieve the effect of "compile PHP script once and run it multiple times". From this point on, PHP is very similar to JAVA's semi-compiled mechanism.

Therefore, from the perspective of operating mechanism, the operating mode of PHP is very similar to that of JAVA. Both intermediate codes are generated first and then run on different virtual machines.

2.5 Dynamic operation

Judging from the above analyses, PHP has done a lot of work in memory management, variables, functions, operating mechanisms, etc. Therefore, from a principle point of view, PHP should not have performance problems, and its performance should be at least as good as Java relatively close.

At this time, we have to talk about the performance issues caused by the characteristics of PHP's dynamic language. Since PHP is a dynamic runtime, all variables, functions, object calls, scope implementation, etc. are determined during the execution phase. . This fundamentally determines some things that are difficult to change in PHP performance: variables and functions that can be determined in the static compilation stage in C/C++ need to be determined in dynamic running in PHP, which also determines that PHP intermediate code cannot Running directly requires running on Zend Engine.

When it comes to the specific implementation of PHP variables, we have to talk about one more thing: Hashtable. Hashtable can be said to be one of the souls of PHP and is widely used within PHP, including variable symbol stacks, function symbol stacks, etc., all based on hashtable.

Take PHP variables as an example to illustrate the dynamic operation characteristics of PHP. For example, the code:


  1. 		<?php 
  2. $var = “hello, blog.xiuwz.com”;  
  3. ?>   
  4.  

该代码的执行结果就是在变量符号栈(是一个hashtable)中新增一个项

大话PHP之性能

当要使用到该变量时候,就去变量符合栈中去查找(也就是变量调用对出了一个hash查找的过程)。

同样对于函数调用也基本上类似有一个函数符号栈(hashtable)。

其实关于动态运行的变量查找特点,在PHP的运行机制中也能看出一些。PHP代码通过解释、编译后的流程下图:

大话PHP之性能

图3 PHP运行实例

从上图可以看出,PHP代码在compile之后,产出的了类符号表、函数符号表、和OPCODE。在真正执行的时候,zend Engine会根据op code去对应的符号表中进行查找,处理。

从某种程度上,在这种问题的上,很难找到解决方案。因为这是由于PHP语言的动态特性所决定的。但是在国内外也有不少的人在寻找解决方案。因为通过这样,能够从根本上完全的优化PHP。典型的列子有facebook的hiphop(https://github.com/facebook/hiphop-php)。

2.6结论

从上面分析来看,在基础的内存管理、变量、函数、运行机制方面,PHP本身并不会存在明显的性能差异,但由于PHP的动态运行特性,决定了PHP和 其他的编译型语言相比,所有的变量查找、函数运行等等都会多一些hash查找的CPU开销和额外的内存开销,至于这种开销具体有多大,可以通过后续的基准 性能和对比分析得出。

因此,也可以大体看出PHP不太适合的一些场景:大量计算性任务、大数据量的运算、内存要求很严格的应用场景。如果要实现这些功能,也建议通过扩展的方式实现,然后再提供钩子函数给PHP调用。这样可以减低内部计算的变量、函数等系列开销。

3.基准性能

对于PHP基准性能,目前缺少标准的数据。大多数同学都存在感性的认识,有人认为800QPS就是PHP的极限了。此外,对于框架的性能和框架对性能的影响很没有响应的权威数字。

本章节的目的是给出一个基准的参考性能指标,通过数据给大家一个直观的了解。

具体的基准性能有以下几个方面:

1.裸PHP性能。完成基本的功能。

2.裸框架的性能。只做最简单的路由分发,只走通核心功能。

3.标准模块的基准性能。所谓标准模块的基准性能,是指一个具有完整服务模块功能的基准性能。

3.1环境说明

测试环境:

 

Uname -a

Linux db-forum-test17.db01.baidu.com 2.6.9_5-7-0-0 #1 SMP Wed Aug 12 17:35:51 CST 2009 x86_64 x86_64 x86_64 GNU/Linux

Red Hat Enterprise Linux AS release 4 (Nahant Update 3)

8  Intel(R) Xeon(R) CPU           E5520  @ 2.27GHz

软件相关:

 

Nginx:

nginx version: nginx/0.8.54  built by gcc 3.4.5 20051201 (Red Hat 3.4.5-2)

Php5:(采用php-fpm)

PHP 5.2.8 (cli) (built: Mar  6 2011 17:16:18)

Copyright (c) 1997-2008 The PHP Group

Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies

with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, by eAccelerator

bingo2:

PHP框架。

其他说明:

目标机器的部署方式:大话PHP之性能 脚本。

测试压力机器和目标机器独立部署。

3.2裸PHP性能

最简单的PHP脚本。


  1. 		<?php 
  2. require_once ‘./actions/indexAction.php’;  
  3. $objAction = new indexAction();  
  4. $objAction->init();  
  5. $objAction->execute();  
  6. ?> 
  7. Acitons/indexAction.php里面的代码如下  
  8. 7b37b5e541546876ae2281b0d782daad   
  9.  

通过压力工具测试结果如下:

大话PHP之性能

3.3裸PHP框架性能

为了和3.2的对比,基于bingo2框架实现了类似的功能。代码如下


  1. 		<?php 
  2. require_once ‘Bingo/Controller/Front.php’;  
  3. $objFrontController = Bingo_Controller_Front::getInstance(array(  
  4. ‘actionDir’ => ‘./actions’,  
  5. ));  
  6. $objFrontController->dispatch();  

压力测试结果如下:

大话PHP之性能

从该测试结果可以看出:框架虽然有一定的消耗,但对整体的性能来说影响是非常小的。

3.4标准PHP模块的基准性能

所谓标准PHP模块,是指一个PHP模块所必须要具体的基本功能:

路由分发。

自动加载。

LOG初始化&Notice日志打印。所以的UI请求都一条标准的日志。

  • 错误处理。
  • 时间校正。
  • 自动计算每个阶段耗时开销。
  • 编码识别&编码转化。
  • 标准配置文件的解析和调用

采用bingo2的代码自动生成工具产生标准的测试PHP模块:test。

测试结果如下:

大话PHP之性能

3.5结论

从测试数据的结论来看,PHP本身的性能还是可以的。基准性能完全能够达到几千甚至上W的QPS。至于为什么在大多数的PHP模块中表现不佳,其实 这个时候更应该去找出系统的瓶颈点,而是简单的说OK,PHP不行,那我们换C来搞吧。(下一个章节,会通过一些例子来对比,采用C来处理不见得有特别的 优势)

通过基准数据,可以得出以下几个具体的结论:

1.PHP本身性能也很不错。简单功能下能够达到5000QPS,极限也能过W。

2.PHP框架本身对性能影响非常有限。尤其是在有一定业务逻辑和数据交互的情况下,几乎可以忽略。

3.一个标准的PHP模块,基准性能能够达到2000QPS(80 cpu idle)。

4.对比分析

很多时候,大家发现PHP模块性能不行的时候,就来一句“ok,我们采用C重写吧”。在公司内,采用C/C++来写业务逻辑模块的现象到处都有,在前几年甚至几乎全部都是采用C来写。那时候大家写的真是一个痛苦:调试难、敏捷不要谈。

文章出自:baidu-tech.com

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/735080.htmlTechArticle1.缘起 关于PHP,很多人的直观感觉是PHP是一种灵活的脚本语言,库类丰富,使用简单,安全,非常适合WEB开发,但性能低下。PHP的性能是否...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn