php5.2与5.3性能比较.docx_第1页
php5.2与5.3性能比较.docx_第2页
php5.2与5.3性能比较.docx_第3页
php5.2与5.3性能比较.docx_第4页
php5.2与5.3性能比较.docx_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PHP5.2与5.3相关比较在递归测试、数值运算测试、字符串操作测试、类和对象测试上5.3性能明显高于5.2,提升大约15%-40%,不过在内存消耗上5.3大于5.2,IO操作速度基本相同。环境1:IIS7+PHP5.3.13环境2:IIS7+PHP5.2.131. 测试递归函数采用交换排序算法对1万个数值元素的数组排序30次,此测试主要测试5.2与5.3在递归调用方面的性能。 1 ) $key = $arr0; $min = array( ); $max = array( ); for( $i = 1; $i $key ) $max = $arr$i; else $min = $arr$i; $min = count( $min ) 0 ? quickSort( $min ) : $min; $max = count( $max ) 0 ? quickSort( $max ) : $max; return array_merge( $min, array( $key ), $max ); else return $arr; /程序运行时间$runTimeNum = 0;$runTime = 0;for( $i = 0; $i 30; $i+ ) $arr = range( 1, 10000 ); shuffle( $arr ); $arr = quickSort( $arr ); $runTimeNum+;$runTime = ( getMsecTime() - $startTime ) / $runTimeNum;echo Running time: , $runTime , ;echo Memory usage: . memory_get_usage();?测试结果:PHP5.3.23:Running time: 0.236173868179320.26386793454488Memory usage:1197432PHP5.2.13:Running time: 0.391258269945780.41212603251139Memory usage:8499202.测试数值计算对指定范围数值做循环加减法操作。?phpfunction getMsecTime() $arr = explode( , microtime() ); return $arr0 + $arr1;/开始时间$startTime = getMsecTime();$numArr = array( 100 , -100 , 1000 , -1000 , 1 );/程序运行时间$runTime = 0;$k = 0;$j = 0;while( $j 1000000 ) $j+; $k += $numArr$j % 5;$runTime = getMsecTime() - $startTime;echo Running time: , $runTime , ;echo Memory usage: . memory_get_usage();测试结果PHP5.3.23:Running time: 0.172901144027710.22068405151367Memory usage: 324440PHP5.2.13:Running time: 0.24252295494080.32152795791626Memory usage: 543603.字符串运算对字符串做一百万次拼接操作。?phpfunction getMsecTime() $arr = explode( , microtime() ); return $arr0 + $arr1;/开始时间$startTime = getMsecTime();/程序运行时间$runTime = 0;$j = 0;$str = ;while( $j 1000000 ) $j+; $str .= $j . abcdefg;$runTime = getMsecTime() - $startTime;echo Running time: , $runTime , ;echo Memory usage: . memory_get_usage();测试结果PHP5.3.23:Running time: 1.07133197784421.2021548748016Memory usage: 13212064PHP5.2.13:Running time: 1.32380199432371.1623599529266Memory usage: 129417524.类和对象速度测试实例化一百万次指定类并调用其类方法。testA = $num; public function getNum() return $this-testA; ;/程序运行时间$runTime = 0;$j = 0;$str = ;while( $j getNum();$runTime = getMsecTime() - $startTime;echo Running time: , $runTime , ;echo Memory usage: . memory_get_usage();测试结果PHP5.3.23:Running time: 2.17981600761412.4962770938873Memory usage: 326560PHP5.2.13:Running time: 4.42904710769654.818235874176Memory usage: 565365.文件IO操作速度测试测试建立、删除、检测文件和文件夹及向文件内写入数据。?phpfunction getMsecTime() $arr = explode( , microtime() ); return $arr0 + $arr1;/开始时间$startTime = getMsecTime();/程序运行时间$runTime = 0;$j = 0;while( $j 1000 ) $j+; $fileName = ./ . $j . test.txt; if( file_exists( $fileName ) ) unlink( $fileName ); file_put_contents( $fileName , $j ); $fileDir = ./ . $j . fileDir; if( is_dir( $fileDir ) & file_exists( $fileDir ) ) rmdir( $fileDir ); mkdir( $fileDir , 0777); $j+;$runTime = getMsecTime() - $startTime;echo Running time: , $runTime , ;echo Memory usage: . memory_get_usage();测试结果PHP5.3.23:Running time: 0.37659287452698 0.46596193313599Memory usage: 326360PHP5.2.13:Running time: 0.351083993911740.46643400192261Memory usage: 56296PHP中的垃圾回收算法5.2中的垃圾回收算法Reference CountingPHP5.2中使用的内存回收算法是大名鼎鼎的Reference Counting,这个算法中文翻译叫做“引用计数”,其思想非常直观和简洁:为每个内存对象分配一个计数器,当一个内存对象建立时计数器初始化为1(因 此此时总是有一个变量引用此对象),以后每有一个新变量引用此内存对象,则计数器加1,而每当减少一个引用此内存对象的变量则计数器减1,当垃圾回收机制 运作的时候,将所有计数器为0的内存对象销毁并回收其占用的内存。而PHP中内存对象就是zval,而计数器就是refcount_gc。Reference Counting简单直观,实现方便,但却存在一个致命的缺陷,就是容易造成内存泄露。很多朋友可能已经意识到了,如果存在循环引用,那么Reference Counting就可能导致内存泄露。例如下面的代码:这段代码首先建立了数组a,然后让a的第一个元素按引用指向a,这时a的zval的refcount就变为2,然后我们销毁变量a,此时a最初指向的zval的refcount为1,但是我们再也没有办法对其进行操作,因为其形成了一个循环自引用,如下图所示:其中灰色部分表示已经不复存在。由于a之前指向的zval的refcount为1(被其HashTable的第一个元素引用),这个zval就不会被GC销毁,这部分内存就泄露了。这里特别要指出的是,PHP是通过符号表(Symbol Table)存储变量符号的,全局有一个符号表,而每个复杂类型如数组或对象有自己的符号表,因此上面代码中,a和a0是两个符号,但是a储存在全局 符号表中,而a0储存在数组本身的符号表中,且这里a和a0引用同一个zval(当然符号a后来被销毁了)。希望读者朋友注意分清符号 (Symbol)的zval的关系。在PHP只用于做动态页面脚本时,这种泄露也许不是很要紧,因为动态页面脚本的生命周期很短,PHP会保证当脚本执行完毕后,释放其所有资源。但是 PHP发展到目前已经不仅仅用作动态页面脚本这么简单,如果将PHP用在生命周期较长的场景中,例如自动化测试脚本或deamon进程,那么经过多次循环 后积累下来的内存泄露可能就会很严重。5.3中的垃圾回收算法Concurrent Cycle Collection in Reference Counted SystemsPHP5.3的垃圾回收算法仍然以引用计数为基础,但是不再是使用简单计数作为回收准则,而是使用了一种同步回收算法,这个算法由IBM的工程师在论文 Concurrent Cycle Collection in Reference Counted Systems中提出。此算法的基本思想:首先PHP会分配一个固定大小的“根缓冲区”,这个缓冲区用于存放固定数量的zval,这个数量默认是10,000,如果需要修改则需要修改源代码Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES然后重新编译。由上文我们可以知道,一个zval如果有引用,要么被全局符号表中的符号引用,要么被其它表示复杂类型的zval中的符号引用。因此在zval中存 在一些可能根(root)。这里我们暂且不讨论PHP是如何发现这些可能根的,这是个很复杂的问题,总之PHP有办法发现这些可能根zval并将它们投入 根缓冲区.当根缓冲区满额时,PHP就会执行垃圾回收,此回收算法如下:1、对每个根缓冲区中的根zval按照深度优先遍历算法遍历所有能遍历到的zval,并将每个zval的refcount减1,同时为了避免对同一zval多次减1(因为可能不同的根能遍历到同一个zval),每次对某个zval减1后就对其标记为“已减”。2、再次对每个缓冲区中的根zval深度优先遍历,如果某个zval的refcount不为0,则对其加1,否则保持其为0。3、清空根缓冲区中的所有根(注意是把这些zval从缓冲区中清除而不是销毁它们),然后销毁所有refcount为0的zval,并收回其内存。如果不能完全理解也没有关系,只需记住PHP5.3的垃圾回收算法有以下几点特性:1、并不是每次refcount减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收。2、可以解决循环引用问题。3、可以总将内存泄露保持在一个阈值以下。PHP5.2与PHP5.3垃圾回收算法的性能比较关于两者的性能比较请参考PHP Manual中的相关章节:/manual/en/features.gc.performance-considerations.php。首先是内存泄露试验,下面直接引用PHP Manual中的实验代码和试验结果图:?php 1. classFoo 2. 3. public$var=3.1415962654; 4. 5. 6. $baseMemory=memory_get_usage(); 7. 8. for($i=0;$iself=$a; 12. if($i%500=0) 13. 14. echosprintf(%8d:,$i),memory_get_usage()-$baseMemory,n; 15. 16. 17. ?可以看到在可能引发累积性内存泄露的场景下,PHP5.2发生持续累积性内存泄露,而PHP5.3则总能将内存泄露控制在一个阈值以下(与根缓冲区大小有关)。另外是关于性能方面的对比:这个脚本执行1000000次循环,使得延迟时间足够进行对比。然后使用CLI方式分别在打开内存回收和关闭内存回收的的情况下运行此脚本:运行时间分别为6.4s和7.2s,可以看到5.3的垃圾回收机制会慢一些,但是影响并不大。与垃圾回收算法相关的PHP配置可以通过修改php.ini中的zend.enable_gc来打开或关闭PHP的垃圾回收机制,也可以通过调用gc_enable()或 gc_disable()打开或关闭PHP的垃圾回收机制。在PHP5.3中即使关闭了垃圾回收机制,PHP仍然会记录可能根到根缓冲区,只是当根缓冲区 满额时,PHP不会自动运行垃圾回收,当然,任何时候您都可以通过手工调用gc_collect_cycles()函数强制执行内存回收。PHP5.3新功能与不兼容特性:新功能:1.支持命名空间PHP5.3之后的版本引入了名称空间的支持,此举的好处是不同模块之间分隔方式变得天然纯正,以往PHP要实现不同模块之间的划分通常会各为其政,有类 PEAR或ZendFramework的, 有像Drupal以模块区分等等,在已有项目内引入了第三方库经常会担心是否有全局名称的冲突,PHP5.3后这种担心可大大减低, 其为我们提供了一种主流解决方案。2.支持GOTO语句3新的静态魔术方法_callStatic.5.2支持通过魔术方法处理不存在方法的调用, 但其只支持非静态方法, 5.3版本引入了静态魔术方法。4.新的匿名魔术方法 _invoke.如果对象实现了_invoke魔术方法就可将其作为函数直接调用,实例化对象之后可用匿名函数的形式直接调用。5.动态调用静态属性。PHP5.2之前静态方法是不支持用变量指定方法名称并动态调用的, 5.3之后引入了此功能。6.支持匿名函数(lumbda).5.3之后引入了匿名函数,对Javascript了解的人对其并不陌生它占了JS的重头戏,灵活运用匿名函数会带来很多便利,PHP的匿名函数作用域和 函数的作用域相同,不过可以通过内置语法USE传入全局变量,当然也可以在函数内部使用global或$GLOBALS调用全局变量。7.新的三元操作符新三元操作符?:在判断表达式结果为TRUE时会返回此判断表达式的结果即?:之前的值, False时返回?:之后的值。8.全局空间内const代替define()函数可直接使用9.json_encode支持强制转换对象JSON5.3后的json_enocde可通过参数强制转换数组为对象形式JSON。10.默认启用SPL支持。SPL提供了很多激动人心的特性,具体包括数据结构类、迭代类、接口、异常、文件等通用功能类。数据结构提

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论