1.缘起
关于PHP,很多人的直观感觉是PHP是一种灵活的脚本语言,库类丰富,使用简单,安全,非常适合WEB开发,但性能低下。PHP的性能是否真的就 如同大家的感觉一样的差呢?本文就是围绕这么一个话题来进行探讨的。从源码、应用场景、基准性能、对比分析等几个方面深入分析PHP之性能问题,并通过真 实的数据来说话。
2.从原理分析PHP性能
从原理分析PHP的性能,主要从以下几个方面:内存管理、变量、函数、运行机制来进行分析。
2.1内存管理
类似Nginx的内存管理方式,PHP在内部也是基于内存池,并且引入内存池的生命周期概念。在内存池方面,PHP对PHP脚本和扩展的所有内存相关操作都进行了托管。对大内存和小内存的管理采用了不同的实现方式和优化,具体可以参考以下文档:https://wiki.php.net/internals/zend_mm。在内存分配和回收的生命周期内,PHP采用一次初始化申请+动态扩容+内存标识回收机制,并且在每次请求结束后直接对内存池进行重新mask。
2.2变量
总所周知,PHP是一种弱变量类型的语言,所以在PHP内部,所有的PHP变量都对应成一种类型Zval,其中具体定义如下:
图一PHP变量
在变量方面,PHP做了大量的优化工作,比如说Reference counting和copy on writer机制。这样能够保证内存使用上的优化,并且减少内存拷贝次数(请参考http://blog.xiuwz.com/2011/11/09 /php-using-internal-zval/)。在数组方面,PHP内部采用高效的hashtable来实现。
2.3函数
在PHP内部,所有的PHP函数都回转化成内部的一个函数指针。比如说扩展中函数
-
ZEND_FUNCTION ( my_function );//类似function my_function(){}
在内部展开后就会是一个函数
-
void zif_my_function ( INTERNAL_FUNCTION_PARAMETERS );
- void zif_my_function(
- int ht,
- zval * return_value,
- zval * this_ptr,
- int return_value_used,
- zend_executor_globals * executor_globals
- );
从这个角度来看,PHP函数在内部也是对应一个函数指针。
2.4运行机制
在话说PHP性能的时候,很多人都会说“C/C++是编译型,JAVA是半编译型,PHP是解释型”。也就是说PHP是先动态解析再代码运行的,所以从这个角度来看,PHP性能必然很差。
的确,从PHP脚本运行来输出,的确是一个动态解析再代码运行的过程。具体来说,PHP脚本的运行机制如下图所示:
图二 PHP运行机制
PHP的运行阶段也分成三个阶段:
- Parse。语法分析阶段。
- Compile。编译产出opcode中间码。
- Execute。运行,动态运行进行输出。
所以说,在PHP内部,本身也是存在编译的过程。并且据此产生了大量的opcode cache工具,比如说apc、eacc、xcache等等。这些opcode cache在生产环境基本上在标配。基于opcode cache,能到做到“PHP脚本编译一次,多次运行”的效果。从这点上,PHP就和JAVA的半编译机制非常类似。
所以,从运行机制上来看,PHP的运行模式和JAVA是非常类似的,都是先产生中间码,然后运行在不同虚拟机上。
2.5动态运行
从上面的几个分析来看,PHP在内存管理、变量、函数、运行机制等几个方面都做了大量的工作,所以从原理来看,PHP不应该存在性能问题,性能至少也应该和Java比较接近。
这个时候就不得不谈PHP动态语言的特性所带来的性能问题了,由于PHP是动态运行时,所以所有的变量、函数、对象调用、作用域实现等等都是在执行 阶段中才确定的。这个从根本上决定了PHP性能中很难改变的一些东西:在C/C++等能够在静态编译阶段确定的变量、函数,在PHP中需要在动态运行中确 定,也就决定了PHP中间码不能直接运行而需要运行在Zend Engine上。
说到PHP变量的具体实现,又不得不说一个东西了:Hashtable。Hashtable可以说在PHP灵魂之一,在PHP内部广泛用到,包含变量符号栈、函数符号栈等等都是基于hashtable的。
以PHP变量为例来说明下PHP的动态运行特点,比如说代码:
-
<?php
- $var = “hello, blog.xiuwz.com”;
- ?>
该代码的执行结果就是在变量符号栈(是一个hashtable)中新增一个项
当要使用到该变量时候,就去变量符合栈中去查找(也就是变量调用对出了一个hash查找的过程)。
同样对于函数调用也基本上类似有一个函数符号栈(hashtable)。
其实关于动态运行的变量查找特点,在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框架。
其他说明:
目标机器的部署方式:脚本。
测试压力机器和目标机器独立部署。
3.2裸PHP性能
最简单的PHP脚本。
-
<?php
- require_once ‘./actions/indexAction.php’;
- $objAction = new indexAction();
- $objAction->init();
- $objAction->execute();
- ?>
- Acitons/indexAction.php里面的代码如下
- <?php
- class indexAction
- {
- public function execute()
- {
- echo ‘hello, world!’;
- }
- }
- ?>
通过压力工具测试结果如下:
3.3裸PHP框架性能
为了和3.2的对比,基于bingo2框架实现了类似的功能。代码如下
-
<?php
- require_once ‘Bingo/Controller/Front.php’;
- $objFrontController = Bingo_Controller_Front::getInstance(array(
- ‘actionDir’ => ‘./actions’,
- ));
- $objFrontController->dispatch();
压力测试结果如下:
从该测试结果可以看出:框架虽然有一定的消耗,但对整体的性能来说影响是非常小的。
3.4标准PHP模块的基准性能
所谓标准PHP模块,是指一个PHP模块所必须要具体的基本功能:
路由分发。
自动加载。
LOG初始化&Notice日志打印。所以的UI请求都一条标准的日志。
- 错误处理。
- 时间校正。
- 自动计算每个阶段耗时开销。
- 编码识别&编码转化。
- 标准配置文件的解析和调用
采用bingo2的代码自动生成工具产生标准的测试PHP模块:test。
测试结果如下:
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
![如何在 iPhone 上使用深度效果 [2023]](https://img.php.cn/upload/article/000/465/014/169410031113297.png)
如果有一件事你可以在iPhone上挑出与众不同,那就是你在处理iPhone的锁定屏幕时拥有的自定义选项的数量。在这些选项中,有深度效果功能,它使您的壁纸看起来像与锁屏时钟小部件交互。我们将解释深度效果,何时何地可以应用它,以及如何在iPhone上使用它。iPhone上的深度效果是什么?当您添加具有不同元素的墙纸时,iPhone会将其拆分为几层深度。为此,iOS利用内置的神经引擎来检测壁纸中的深度信息,将您想要出现在焦点中的主题与所选背景的其他元素分开。这将产生一种看起来很酷的效果,其中墙纸中的主

不包含任何循环或回路的图被称为非循环图。树是一种非循环图,其中每个节点都与另一个唯一节点相连。非循环图也被称为无环图。循环图与非循环图的区别-CycleGraph的中文翻译为:循环图非循环图图形形成一个闭环。图表没有形成闭环。图表中不包含深度循环图表包含每个深度。示例1让我们举一个循环图的例子−当闭环存在时,就形成了循环图。FigureI代表了循环图,不包含深度节点。Example2的翻译为:示例2让我们以一个非循环图的例子来说明:树的根节点称为零深度节点。在图II中,在零深度处只有一个根,即2

Django框架是一种用于Web应用程序的Python框架,它提供了一个简单而强大的方式来创建Web应用程序。事实上,Django已经成为当前最受欢迎的PythonWeb开发框架之一,也成为很多公司的首选,包括Instagram和Pinterest。本文将深入探讨Django框架是什么,包括基础概念和重要组件,以及具体代码示例。Django基础概念Djan

作为一个流行的PHP框架,Laravel提供了许多便捷的请求方法来处理不同类型的HTTP请求。其中,Head请求方法是一个比较特殊且常被忽视的方法。在本文中,我们将深入探讨Laravel中Head请求方法的作用、用法和示例代码。什么是Head请求方法?Head请求方法是HTTP协议中定义的一种请求方法,在发送Head请求时,服务器将仅返回请求头信息,而不会返

Go语言是一门由Google开发的编程语言,具有高效、简洁、并发性强等特点。它在语法结构、包管理、高级特性等方面都有很大的优势,因此备受程序员青睐。然而,在实际开发中,很多项目会涉及到与传统的编程语言C进行交互,因此Go语言与C语言的兼容性就显得尤为重要。首先,我们来谈谈Go语言与C语言的兼容性。在Go语言中,可以通过CGo将Go语言与C语言进行交互。CGo

Golang是一种由谷歌开发的编程语言,其出色的性能和并发特性使其在各种领域中得到了广泛的应用,包括网络编程、大数据处理等。然而,对于一些需要直接操作硬件的领域,比如驱动程序开发,人们可能会开始思考:Golang是否适合用于编写驱动程序呢?本文将深入探讨这个问题,并通过具体的代码示例来展示Golang在驱动程序开发中的应用。首先,让我们来了解一下什么是驱动程

简要介绍研究作者提出了 Matrix Net (xNet),一种用于目标检测的新深度架构。xNets将具有不同大小尺寸和纵横比的目标映射到网络层中,其中目标在层内的大小和纵横比几乎是均匀的。因此,xNets提供了一种尺寸和纵横比感知结构。研究者利用xNets增强基于关键点的目标检测。新的的架构实现了比任何其他单镜头检测器的时效性高,具有47.8的mAP在MS COCO数据集,同时使用了一半的参数而且相比于第二好框架,其在训练上快了3倍。简单结果展示上图所示,xNet的参数及效率要远远超过其它模型

Go语言作为一种现代化的编程语言,以其简洁高效的特性在近年来受到越来越多开发者的喜爱和青睐。其中一个让人独特的地方就是其单线程特性。在传统的多线程编程语言中,开发者通常需要手动管理线程之间的同步和互斥,而在Go语言中,借助其独特的协程(Goroutine)和通信机制(channel),可以方便且高效地实现并发编程。一、Goroutine与单线程:Go语言中的


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.
