`
wx1569632409
  • 浏览: 116304 次
文章分类
社区版块
存档分类
最新评论

PHP 性能分析与实验

 
阅读更多

对 PHP 性能的分析,我们从两个层面着手,把这篇文章也分成了两个部分,一个是宏观层面,所谓宏观层面,就是 PHP 语言本身和环境层面,一个是应用层面,就是语法和使用规则的层面,不过不仅探讨规则,更辅助以示例的分析。

宏观层面,也就是对 PHP 语言本身的性能分析又分为三个方面:

  1. PHP 作为解释性语言性能有其天然的缺陷
  2. PHP 作为动态类型语言在性能上也有提升的空间
  3. 当下主流 PHP 版本本身语言引擎性能

一、PHP 作为解释性语言的性能分析与提升

PHP 作为一门脚本语言,也是解释性语言,是其天然性能受限的原因,因为同编译型语言在运行之前编译成二进制代码不同,解释性语言在每一次运行都面对原始脚本的输入、解析、编译,然后执行。如下是 PHP 作为解释性语言的执行过程。

千锋php官方所有

图1、PHP 语言解析运行过程

如上所示,从上图可以看到,每一次运行,都需要经历三个解析、编译、运行三个过程。

那优化的点在哪里呢?可以想见,只要代码文件确定,解析到编译这一步都是确定的,因为文件已不再变化,而执行,则由于输入参数的不同而不同。在性能优化的世界里,至上绝招就是在获得同样结果的情况下,减少操作,这就是大名鼎鼎的缓存。缓存无处不在,缓存也是性能优化的杀手锏。于是乎 OpCode 缓存这一招就出现了,只有第一次需要解析和编译,而在后面的执行中,直接由脚本到 Opcode,从而实现了性能提速。执行流程如下图所示:

 

图2. 启用了 opcode 缓存的 PHP 运行过程

相对每一次解析、编译,读到脚本之后,直接从缓存读取字节码的效率会有大幅度的提升,提升幅度到底有多大呢?

我们来做一个没有 Opcode 缓存的实验。20 个并发,总共 10000 次请求没有经过 opcode 缓存的请求,,得到如下结果:

 

图3. 没有使用Opcode缓存的请求,20个并发,10000次

其次,我们在服务器上打开 Opcode 缓存。要想实现 opcode 缓存,只需要安装 APC、Zend OPCache、eAccelerator 扩展即可,即使安装了多个,也只启用其中一个。注意的是,修改了 php.ini 配置之后,需要重新加载 php-fpm 的配置。

这里分别启用 APC 和 Zend OPCache 做实验。启用 APC 的版本。

 

图4、启用APC 缓存加速的实验结果

可以看到,速度有了较大幅度的提升,原来每个请求 110ms,每秒处理请求 182 个,启用了 APC 之后 68ms,每秒处理请求 294 个,提升速度将近 40%。

在启用了 Zend Opcache 的版本中,得到同 APC 大致相当的结果。每秒处理请求 291 个,每请求耗时 68.5ms。

 

图5、启用OpCode Cache 的性能分析结果

从上面的这个实验可以看到,所用的测试页面,有 40ms 以上的时间花在了语法解析和编译这两项上。通过将这两个操作缓存,可以将这个处理过程的速度大大提升。

这里附加补充一下,OpCode 到底是什么东东,OpCode 编译之后的字节码,我们可以使用bytekit 这样的工具,或者使用 vld PHP 扩展来实现对 PHP 的代码编译。如下是 vld 插件解析代码的运行结果。

 

图6、vld 扩展反编译出来的PHP代码的字节码

可以看到每一行代码被编译成相应的 OpCode 的输出。

二、PHP 作为动态类型语言的性能分析与改进

第二个是 PHP 语言是动态类型的语言,动态类型的语言本身由于涉及到在内存中的类型推断,比如在 PHP 中,两个整数相加,我们能得到整数值,一个整数和一个字符串相加,甚至两个字符串相加,都变成整数相加。而字符串和任何类型连接操作都成了字符串。

 
  1. <?php
  2. $a = 10.11;
  3. $b = "30";
  4. var_dump($a+$b);
  5. var_dump("10"+$b);
  6. var_dump(10+"20");
  7. var_dump("10"+"20");

运行结果如下:

 
  1. float(40.11)
  2. int(40)
  3. int(30)
  4. int(30)

语言的动态类型为开发者提供了方便,语言本身则会因为动态类型而降低效率。在 Swift 中,有一个特性叫类型推断,我们可以看看类型推断会带来多大的一个效率上的差别呢?对于需要类型推断与不需要类型推断两段 Swift 代码,我们尝试编译一下看看效果如何。 第一段代码如下:

 

图 7、要使用类型推断的 Swift代码

这是一段 Swift 代码,字典只有 14 个键值对,这段代码的编译,9 分钟了还没有编译完成(5G 内存,2.4GHz CPU),编译环境为 Swift 1.2,Xcode 6.4。

 

图8、使用类型推断的 Swift 代码,编译速度很慢

但是如果调整代码如下:

 

图9、避免了复杂数据类型推断的代码

也就是加上了类型限定,避免了 planeLocation 的类型推断。编译过程花了 2S 。

 

图10、减少了类型推断之后,编译速度大幅度提升

可见,作为动态类型附加的类型推断操作极大地降低了程序的编译速度。 当然,这个例子有点极端,用 Swift 来类比 PHP 也不一定合适,因为 Swift 语言本身也还在不断的进化过程中。本例子只是表明在编程语言中,如果是动态类型语言,就涉及到对动态类型的处理,从编译的角度讲是会受影响的。

那么作为动态类型的 PHP 的效率如何提升呢?从 PHP 语言本身这个层面是没有办法解决的,因为你怎么写也是动态类型的代码。解决办法就是将PHP转化为静态类型的表示,也就是做成扩展,可以看到,鸟哥的很多项目,比如 Yaf 框架,都是做成了扩展的,当然这也是由于鸟哥是 C 高手。扩展由于是 C 或者 C++ 而写,所以不再是动态类型,又加之是编译好的,而 C 语言本身的效率也会提升很多。所以效率会大幅度提高。

下面我们来看一段代码,这段代码,只是实现了简单的素数运算,能计算指定值以内的素数个数,用的是普通的筛选法。现在看看扩展实现,跟 PHP 原生实现的效率差别,这个差别当然,不仅仅是动态类型和编译类型的差别,还有语言效率的差别。

首先是用纯 PHP 写成的算法,计算 1000 万以内的素数个数,耗时在 33s 上下,实验了三次,得到的结果基本相同。

 

图11、在PHP 5.3中,筛选法求素数的效率

其次,我们将这个求素数个数的过程,编写成了 PHP 扩展,在扩展中实现了 getprimenumbers 函数,输入一个整数,返回小于该整数的素数。得到的结果如下,这个效率的提升是非常惊人的,在 1.4s 上下即返回。速度提升 20 倍以上。

 

图12、在PHP 5.3中,改造成扩展后筛选法求素数的效率

可以想见,静态和编译类型的语言,其效率得到了惊人的提升。本程序的 C 语言代码如下:

 
  1. PHP_FUNCTION(get_prime_numbers)
  2. {
  3. long value;
  4. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == FAILURE) {
  5. return;
  6. }
  7. int *numbers = (int *)malloc(sizeof(int)*128*10000);
  8. memset(numbers, 0x0, 128*10000);
  9. int num = 2;
  10. numbers[0] = 2;
  11. numbers[1] = 3;
  12. bool flag = true;
  13. double f = 0;
  14. int i = 0;
  15. int j = 0;
  16. for(i=5; i<=value; i+=2)
  17. {
  18. flag = true;
  19. f = sqrt(i);
  20. for(j=0; j<num;j++)
  21. {
  22. if(i%numbers[j]==0)
  23. {
  24. flag = false;
  25. break;
  26. }
  27. if(numbers[j]>f)
  28. {
  29. break;
  30. }
  31. }
  32. if(flag)
  33. {
  34. numbers[num] = i;
  35. num++;
  36. }
  37. }
  38. free(numbers);
  39. RETURN_LONG(num);
  40. }

三、PHP 语言本身底层性能引擎提升

第三个性能优化层面是语言本身的性能提升,这个就不是我们普通开发者所能做的了。在 PHP 7以前,寄希望于小版本的改进,但是改进幅度不是非常的显著,比如 PHP 5.3 、PHP 5.4、PHP 5.5、PHP 5.5 对同一段代码的性能比较,有一定程度的进步。

PHP 5.3 的版本在上面的例子中已讲过,需要 33s 左右的时间,我们现在来看别的PHP版本。分别运行如下:

PHP 5.4 版,相较 5.3 版已经有一定程度的提升。快 6 秒左右。

 

图13、在PHP 5.4中,筛选法求素数的效率

PHP 5.5 版在 PHP 5.4的基础上又进了一步,快了 6S。

 

图14、在PHP 5.5中,筛选法求素数的效率

PHP5.6 反而有些退步。

 

图15、在PHP 5.6中,筛选法求素数的效率

PHP 7 果真是效率提升惊人,是 PHP5.3 的 3 倍以上。

 

图16、在PHP 7中,筛选法求素数的效率

以上是求素数脚本在各个 PHP 版本之间的运行速度区别,尽管只测试了这一个程序,也不是特别的严谨,但是这是在同一台机器上,而且编译 configure 参数也基本一样,还是有一定可比性的。

在宏观层面,除了上面的这些之外,在实际的部署过程中,对 PHP 性能的优化,还体现为要减少在运行中所消耗的资源。所以 FastCGI 模式和 mod_php 的模式比传统的 CGI 模式也更为受欢迎。因为在传统的 CGI 模式中,在每一次脚本运行都需要加载所有的模块。而在程序运行完成了之后,也要释放模块资源。如下图所示:

 

PHP性能分析与实验(一)

而在 FastCGI 和 mod_php 模式中,则不需要如此。只有 php-fpm 或者 Apache 启动的时候,需要加载一次所有的模块,在具体的某次运行过程中,并不需要再次加载和释放相关的模块资源。

 

 


更多PHP相关技术请搜索千锋PHP,做真实的自己,用良心做教育。

 

互联网+时代,时刻要保持学习,携手千锋PHP,Dream It Possible。

转载于:https://my.oschina.net/u/3432750/blog/911848

分享到:
评论

相关推荐

    PHP版LIMS(开放实验室信息管理系统)

    LIMS,全称为Laboratory Information Management System,即实验室信息管理系统,主要用于实验室数据的采集、管理、分析以及报告等各个环节,提高实验室的工作效率和数据准确性。在本文中,我们将深入探讨一个由外籍...

    进程调度算法模拟实现与性能分析

    最后,进程调度算法的模拟实现与性能分析是一个复杂的过程,它不仅需要对操作系统原理的深入理解,还需要具备良好的编程能力和实验设计能力。通过C语言的模拟和实验数据分析,研究者可以验证不同调度算法在实际应用...

    nginx的七个实验

    实验会使用工具(如ab或JMeter)模拟并发请求,分析Nginx的性能表现,以及如何调整配置以优化并发处理。 7. **Nginx日志分析** 日志分析是监控服务器状态和优化性能的关键步骤。Nginx的日志格式灵活,可以自定义。...

    基于php实验室管理系统设计与实现.docx

    随着技术的发展,可以考虑引入云计算、大数据分析等技术,进一步提升实验室管理的智能化水平。 总结,基于PHP的实验室管理系统通过B/S架构和MySQL数据库实现了高效的实验室管理。该系统不仅简化了管理流程,还促进...

    PHP基础案例教程配套实验代码

    通过分析和实践这些实验代码,你将能逐步掌握PHP编程的核心技能,并为更高级的Web开发打下坚实的基础。记得,理论与实践相结合是学习任何编程语言最有效的方式,所以不仅要阅读代码,还要尝试修改和运行它们,以加深...

    信息安全实验三:Snort入侵检测系统的配置与使用

    实验不仅涉及Snort的基本安装与配置,还包括如何搭建一个完整的网络入侵检测系统平台,其中包括Snort、Windows、MySQL、PHP以及ACID等组件的集成。此外,学生还将学习如何编写简单的Snort规则,并理解Snort的检测...

    毕业论文php41在线实验教学平台.doc

    在本设计中,我们使用面向对象分析与设计(OOA)来设计在线实验教学平台。面向对象分析与设计是一种软件开发方法,强调将系统分解成多个对象,每个对象都有其自己的属性和行为。该方法可以帮助我们更好地设计和实现...

    PHP实验报告.pdf

    "PHP实验报告.pdf" 以下是从给定的文件中生成的相关知识点: 一、网站开发基础 * 网站开发需要选择合适的域名和空间,需要学习如何购买和使用域名和空间。 * 了解网站开发工具的使用,如PHP、HTML、CSS等。 二、...

    供求信息网网站系统分析与设计报告实验报告.pdf

    从技术角度来看,选择PHP作为开发语言,因为它支持面向对象编程,适合大型项目,执行效率高,配置简单,跨平台性强,与MySQL数据库和Apache服务器配合使用,能最大化系统性能。经济可行性方面,考虑到网站已经成为...

    毕业论文php205软件实验报告管理系统.doc

    【PHP软件实验报告管理系统...总的来说,这篇毕业论文详细介绍了基于PHP的软件实验报告管理系统的开发过程,涵盖了从需求分析、系统设计到实现与测试的各个环节,充分展示了Web开发技术在解决实际问题中的应用价值。

    高效镀镍整平剂PHP某些电化学性能的研究.pdf

    本文主要研究了高效镀镍整平剂PHP的电化学性能,通过电容曲线和旋转圆盘电极上的循环伏安溶出法分析了PHP的吸附特性和整平能力。研究表明PHP在汞电极上的吸附较弱,但具有出色的整平能力,并与醇醚化物存在协同作用...

    php msql apach实验报告4

    #### 五、实验结果分析与总结 - **PHP 对设置文件的支持**: - PHP 的配置文件 php.ini 定义了各种配置项,如数据库连接超时、会话存储方式等。 - 开发者可以通过修改 php.ini 文件来调整 PHP 的运行参数,以满足...

    遗传算法的计算性能的统计分析.pdf

    #### 遗传算法的计算性能分析 论文摘要部分简要介绍了研究的主要内容,即通过对多维解析函数的重复计算和统计分析来评估遗传算法的可靠性和可信度。主要观点包括: - **遗传算法的稳定性**:遗传算法虽然具有随机性...

    基于php实验室预约排课系统设计与实现.docx

    【基于PHP实验室预约排课系统设计与实现】 实验室预约排课系统是高校教学管理中的重要组成部分,对于优化教学资源分配,提升教学效率有着至关重要的作用。传统的实验室预约和排课方式依赖于人工操作,不仅效率低下...

    基于PHP+MYSQL技术的实验排课系统研究.pdf

    4. 实验排课系统的设计方法:实验排课系统的设计方法主要包括需求分析、系统设计、数据库设计、实现和测试等阶段。需求分析阶段需要了解用户的需求和业务流程,系统设计阶段需要设计系统的总体架构和模块,数据库...

    MyPetShop实验报告书.doc

    实验结束后,学生通常会分享他们的体验、遇到的问题、解决问题的方法,以及对Web程序设计更深入的理解,包括安全性、性能优化、用户体验等方面的思考。 总结,MyPetShop实验报告书是学习Web程序设计的重要实践项目...

Global site tag (gtag.js) - Google Analytics