`
isiqi
  • 浏览: 16485441 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论
阅读更多

PHP程序加速探索
Haohappy 2004-07-27
haohappy@msn.com

- (一)简介
- (二)是否需要加速?
- (三)如何加速?
-<1> 测试
服务器负载测试 ApacheBench
脚本执行速度测试 PEAR:: Benchmark
-<2> 加速
代码优化
压缩输出 Gzip
内容缓存输出 PEAR Content cache
函数缓存输出 PEAR Function cache
加速工具软件 APCTurck MMCachePHPAZend Performance Suite
- (四)总结

(一)简介
本文尝试对PHP程序加速的各个方面进行探索,包括必要性以及从不同角度采取的具体措施。希望有助于读者了解PHP程序加速,并应用于实际。
(二)是否需要加速?
这个问题听起来有点愚蠢。在这个时代,很少有人会怀疑时间是最宝贵的财富,尤其是在商业市场上。程序执行越快,用户就节约越多的时间,这样你的程序就可以用更少的时间和服务器资源为用户服务,从而产生更多效益。
我想对于大部份人(包括我自己)来说,很多WEB项目都是在很紧张的时间里完成的,通常没有经过缜密的思考和严格的测试。当开始一个新的WEB项目。很多人都在构建那种“快而乱”的应用,缺乏必要的时间来调整和改良代码,这时优化和加速就是我们必须采取的措施。
然而需要特别指出的是,并不是所有程序都需要加速。
优化已完成的代码是很浪费时间的,最好的方法是在写代码的时候就注意到效率,然后完成项目后只优化确实需要优化的那部份。一般一个程序只会有少数几个影响速度的瓶颈,将它们找出来并解决掉,程序就可以很好地运行。另外,当遇到执行效率低下的情况,首先要用大局的眼光来找出影响效率的主要因素,而不要拘泥于细节例如数据量过大,服务器带宽不够,或硬件配置过低,在这样的情况下,优化代码于事无补。
另外,在没有发现程序有明显的执行缓慢的迹象时,就不要太吹毛求疵,为了改进一些非常细节的代码而浪费时间。用这些时间,你可以完成另一个项目或为原来的项目完成一个扩展功能。当然你可以笑话我不够负责,没有把工作做得尽善尽好,我也可以说你是完美主义者:-)  
综上,在你决定为你的PHP程序提速之前,问问自己是否有必要。
(三)如何加速?
要回答“如何加速”这个问题前,需要先回答以下两个小问题:
1. 你的程序慢在哪一部份?
2. PHP可以从哪几个方面考虑加速?
第一个小问题显然我无法给你答案,但我建议你用“测试脚本执行速度”的方法来解决。只有找出限制速度的瓶颈,才能考虑如何去解决。
第二个小问题我大概的答案是:代码优化,压缩输出,内容缓存输出,函数缓存输出,加速/缓存工具软件。如果你知道更多请告诉我:-)
下面我们来详细地研究一下这几个方面的相关技术。当然实际上每个方面都有无数的细节可以讨论,下面的内容难免会有片面的地方,欢迎补充。

<1> 测试

服务器负载测试

服务器负载太大而影响程序效率也是很常见的,我们需要对此进行测试。这里我以目前最常用的Apache服务器为例。

Apache服务器自带有一个叫AB(ApacheBench)的工具,在bin目录下。使用这个轻巧的工具我们可以对服务器进行负载测试,看看在重负荷之下服务器的表现如何。ApacheBench 可以针对某个特定的 URL 仿真出连续的联机请求,同时还可以仿真出同时间点数个相同的联机请求,因此利用 ApacheBench 可帮助我们在网站开发期间仿真实际上线可能的情况,利用仿真出来的数据作为调整服务器设定或程序的依据。

在命令行下输出:

./ab -n number_of_total_requests \
-c number_of_simultaneous_requests \
http://your_web_server/your_php_app.php

例如:

./ab -n 1000 -c 50 http://www.domain.com/myapp.php

AB将同时向http://www.domain.com/myapp.php发出50个并发请求,共发出1000次。

测试结果将可能是这样的:

Server Software: Apache/2.0.16
Server Hostname: localhost
Server Port: 80
Document Path: /myapp.php
Document Length: 1311 bytes
Concurrency Level: 50
Time taken for tests: 8.794 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 1754000 bytes
HTML transferred: 1311000 bytes
Requests per second: 113.71
Transfer rate: 199.45 kb/s received
Connection Times (ms)
min avg max
Connect: 0 0 5
Processing: 111 427 550
Total: 111 427 555

myapp.php每秒钟可以处理的请求数为113.71个。将请求数增加,看看服务器能否处理更大的压力。你也需要调节ApacheMaxClients,ThreadsPerChild,MaxThreadsPerChild等参数,基于你的httpd.conf中的MPM模块选择。

如果你想得到更详细的信息,请到www.apache.org上查阅一些更深入的文档,包括模块和第三方的提高效率的工具。修改httpd.conf后,要重启Apache服务器,然后再用AB测试。你会看到每秒请求数增加或减少。

记下每次的参数,最后选择最佳效率的那种配置。

要指出的是,除了AB,还有许多优秀的服务器性能测试软件。另外,如果你的服务器不是Apache,请自行寻找测试方法。

脚本执行速度测试

前面有提到,只有找到影响速度的代码,我们才有可能进行优化。PEARbenchmark包中的Benchmark_Timer类和Benchmark_Iterate类,可以用来很方便地测试脚本执行的速度。(关于PEAR的安装与配置请自行查看相关资料)

首先用Benchmark_Iterate来测试程序中某个函数或类的某个方法的执行时间。

benchmark1.php


require_once('Benchmark/Iterate.php');
$benchmark = new Benchmark_Iterate();

$benchmark->run(10, 'myFunction','test');
$result = $benchmark->get();
echo
" ;
exit;

function
myFunction($var) {
// do something
echo 'Hello ';
}

?>

"; 
print_r($result);
echo
"

"

建立benchmark Iterate对象$benchmark,这个对象用来执行myFunction函数10次。

$argument变量每次都传递给myFunction. 多次运行的分析结果存入$result,然后用benchmark对象的get()方法来获取。这个结果用print_r()输出到屏幕。通常会输出这样的结果:

Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello

Array
(
 [1] => 0.000427
[2] => 0.000079
[3] => 0.000072
[4] => 0.000071
[5] => 0.000076
[6] => 0.000070
[7] => 0.000073
[8] => 0.000070
[9] => 0.000074
[10] => 0.000072
[mean] => 0.000108
[iterations] => 10
)

myFunction的每次执行,benchmark对象都会跟踪执行时间。并且会计算平均的执行时间([mean]那一行)。通过多次运行目标函数,你可以得到该函数的平均运行时间。

在实际测试中,函数的次数应当至少1000次左右,这样可以得到较客观的结果。

现在我们看看另一个测试脚本运行时间的方法--使用Benchmark_Timer类来测试一段代码执行所消耗的时间及这一段代码中每次调用与下一次调用间的时间。

benchmark2.php


require_once 'Benchmark/Timer.php';
$timer = new Benchmark_Timer();

$timer->start();
$timer->setMarker('start_myFunction');

for(
$i=0; $i<10; $i++){
myFunction($argument);
}
$timer->setMarker('end_myFunction');
$timer->stop();
$profiling = $timer->getProfiling();

echo
' .
$timer->timeElapsed('start_myFunction','end_myFunction') .'

Time elapsed: '

';
echo
' ;
exit;

function
myFunction($var) {
static
$counter = 0;
// do something
echo $counter++ . ' ';
}
?>

'; 
print_r($profiling);
echo
'

'

首先,建立一个benchmark timer对象$timer。然后调用start()方法,表示开始计时。 SetMaker()方法用来标记要测试的代码段。MyFunction()函数在循环中被调用,表示一段要执行的代码(当然实际中不会这么简单)。然后再用$timer对象的setMarker()方法标记程序执行终点。分析信息用getProfiling()来获取。在两个标记间程序执行消耗的时间用timeElapsed()方法计算出来(就像例子中的循环)。最后,用print_r()输出信息到屏幕:

0 1 2 3 4 5 6 7 8 9

Time elapsed: 0.000594

Array
(
 [0] => Array
 (
 [name] => Start
[time] => 1085730111.27175200
[diff] => -
[total] => 1085730111.271752
 )
 [1] => Array
 (
 [name] => start_myFunction
[time] => 1085730111.27203800
[diff] => 0.000286
[total] => 1085730111.272038
)
 [2] => Array
 (
 [name] => end_myFunction
[time] => 1085730111.27263200
[diff] => 0.000594
[total] => 1085730111.272632
)
 [3] => Array
 (
 [name] => Stop
[time] => 1085730111.27271800
[diff] => 0.000086
[total] => 1085730111.272718
)
)

通过这种方法,你可以在代码中设置大量时间段标记,获取每段代码执行时消耗的时间,很容易可以看出到底是哪一部份的代码影响了整个程序的运行效率。然后开始着手对这部份代码进行改进。

用以上两种方法,你可以找出代码中最影响速度的部份代码。另外还可以用来对优化后的代码进行测试,看看到底执行速度提高了多少。通过测试->优化->测试->优化这样不断循环,你可以最终确定提供最佳效率的代码。

<2> 加速

代码优化

掌握了PEAR::BenchMark,现在你已经知道如何测试你的代码,知道如何判断你的代码是快是慢,是哪一部份比较慢。那么接下来我要说的就是如何消灭或优化那部份慢的代码。

这一点上我个人最主要的经验只有两点,一是消除错误的或低效的循环;二是优化数据库查询语句。其实还存在一些其它的优化细节,比如“str_replaceereg_replace快”、“echoprint快”等等。这些我暂时都放在一边,稍后我会提到用缓存来对付过于频繁的IO

下面我们将三个功能相同,但程序写法不同的函数的效率(消耗的时间)进行对比。

badloops.php

<?php
require_once('Benchmark/Iterate.php');
define('MAX_RUN',100);
$data = array(1, 2, 3, 4, 5);

doBenchmark('v1', $data);
doBenchmark('v2', $data);
doBenchmark('v3', $data);
function
doBenchmark($functionName = null, $arr = null)
{
reset($arr);
$benchmark = new Benchmark_Iterate;
$benchmark->run(MAX_RUN, $functionName, $arr);
$result = $benchmark->get();
echo
'<br>';
printf("%s ran %d times where average exec time %.5f ms",$functionName,$result['iterations'],$result['mean'] * 1000);
}

function
v1($myArray = null) {
// 效率很差的循环
for ($i =0; $i < sizeof($myArray); $i++)
{
echo
'<!--' . $myArray[$i] . ' --> ';
}
}


function
v2($myArray = null) {
// 效率略有提高
$max = sizeof($myArray);
for (
$i =0; $i < $max ; $i++)
{
echo
'<!--' . $myArray[$i] . ' --> ';
}
}

function
v3($myArray = null){
//最佳效率
echo "<!--", implode(" --> <!--", $myArray), " --> ";
}

?>

程序输出的结果大概是这样的:

v1 ran 100 times where average exec time 0.18400 ms
v2 ran 100 times where average exec time 0.15500 ms
v3 ran 100 times where average exec time 0.09100 ms

可以看到,函数的执行时间变少,效率上升。

函数v1有个很明显的错误,每一次循环的时间,都需要调用sizeof()函数来计算。函数v2则在循环外把$myArray数组的元素个数存到$max变量中,避免了每次循环都要计算数组的元素个数,所以效率提高了。函数v3的效率最高,利用了现成的函数,避免循环。

这个例子只是给你一个感性的认识,明白什么是相对高效的代码。在实际开发中,我相信会有很多人会迷迷糊糊地写出很多低效率的代码。要把代码写得精炼而高效,恐怕需要时间去锤炼:-)但这是另一个话题了,我们略过不谈。

数据库应用基本上每个PHP程序都会用到,在实际开发中我发现最影响整个系统效率的就是数据库这部份。至于数据库的优化和数据查询语句的优化,在此限于篇幅不详细讨论。你可以参看这两篇文章:

http://www.phpe.net/articles/340.shtml

http://www.phpe.net/articles/323.shtml

及这篇讨论:

http://club.phpe.net/index.php?s=&act=ST&f=15&t=4783&st=0

(前面几篇贴子总结不错)

主要是针对MySQL的。

压缩输出 gzip

利用Apache中的mod_gzip模块,我们可以利用gzip的压缩算法来对Apache服务器发布的网页内容进行压缩后再传输到客户端的浏览器。如果是纯文本的内容,效果非常明显,大约可以压缩到原来的30%-40%,使用户的浏览速度大大加快。

Gzip需要客户端浏览器支持,目前大部份浏览器都支持gzip,如IENetscape,Mozilla等,所以这种方法值得一试。我们可以利用PHP中的预定义变量$_SERVER[‘HTTP_ACCEPT_ENCODING’]来判断客户端浏览器是否支持gzip

gzip1.php</

分享到:
评论

相关推荐

    PHP程序加速探索之加速工具软件

    为了提升PHP程序的运行速度,开发人员通常会利用各种加速工具软件,这些工具主要通过对PHP执行码进行优化和缓存来提升效率,无需修改原始代码。本文将探讨几种常用的PHP执行码优化/缓存工具。 首先,我们有APC ...

    PHP程序加速探索之脚本执行速度测试

    为了实现这一目标,我们需要对代码进行性能分析,找出耗时的瓶颈。... ...`Benchmark_Timer`类主要用于测量单次操作的时间...在实际开发过程中,不仅要关注功能的实现,也要关注代码的性能,这样才能编写出高质量的PHP程序。

    PHP程序加速探索之缓存输出

    本文主要探讨的是使用PEAR(PHP Extension and Application Repository)库中的Cache组件进行内容缓存输出,以实现PHP程序的加速。 首先,了解缓存的基本原理:缓存是将频繁访问的数据暂存到高速存储设备中,以便...

    PHP程序加速探索之代码优化

    在PHP编程中,代码优化是提升程序性能的关键环节。通过使用工具如PEAR::BenchMark,我们可以有效地测试和分析代码的执行效率,从而找到代码中的瓶颈。本文将深入探讨如何优化那些运行较慢的代码段,主要关注两个核心...

    PHP程序加速探索之压缩输出gzip

    这里我们关注的是PHP程序的加速,特别是通过使用Apache服务器上的mod_gzip模块实现的压缩输出,以gzip算法来压缩网页内容,减少传输的数据量,从而加快用户浏览速度。 gzip是一种广泛使用的数据压缩算法,尤其适合...

    php学习电子书php 教程

    17. PHP框架:熟悉常见的PHP框架,如Laravel、Symfony、Yii等,它们提供了一套完整的开发规范和工具,加速项目开发。 八、安全性 18. 输入验证:对用户输入进行过滤和验证,防止SQL注入、跨站脚本攻击(XSS)等安全...

    php基础学习

    7. **PEAR**:PEAR是PHP的扩展和应用程序仓库,提供了一系列已封装好的PHP类库,便于开发者快速构建和维护项目,遵循一致的编码标准和最佳实践。 8. **XML处理**:XML作为一种数据交换格式,PHP提供了DOM、...

    基于PHP的最新装逼神器生成系列 php版.zip

    12. **框架与CMS**:PHP有众多流行的框架(如Laravel、Symfony、Yii)和内容管理系统(如WordPress、Drupal、Joomla),加速开发进程。 13. **PHP版本更新**:PHP的最新版本通常包含性能优化、新特性和安全改进,...

    PHP常用代码大全

    《PHP常用代码大全》这一资料集,为广大的PHP开发者提供了丰富的编程素材和实用的代码片段,涵盖了PHP语言的核心功能和常见应用场景,是提升开发效率、...希望每位读者都能从中获得灵感,不断探索PHP编程的广阔天地。

    php+mysql 经典教程

    8. PHP框架简介:简单介绍一些流行的PHP框架,如Laravel、Symfony和CodeIgniter,让读者了解如何利用框架加速开发进程。 9. 实践项目与调试:通过实际项目来巩固所学知识,学习如何使用版本控制工具(如Git),以及...

    PHP for Flash FMS网站开发手札.pdf

    本书通过介绍几种流行的AMF-RPC实现,如Zend_Amf、AMFPHP和SabreAMF,不仅阐述了这些框架的基本原理,还提供了丰富的实战案例,帮助开发者理解和运用AMF-RPC技术,以加速应用程序的开发过程。 ### Flash实时通信...

    PHP_JTBC_CMS.tar.gz_CMS + PHP_JTBC_cms php_php cms

    2. **JTBC框架**: JTBC(Just Too Beautifully Created)是一个轻量级的PHP框架,旨在简化Web应用程序的开发过程。它可能包含了MVC(Model-View-Controller)设计模式,使得代码结构清晰,易于维护。框架可能还提供...

    php贴吧项目实战源码+数据库

    最后,可能会涉及一些优化技巧,如使用索引来加速查询,以及缓存策略来减轻数据库负载。 通过这个PHP贴吧项目实战,你不仅能够巩固PHP编程基础,还能深入了解Web开发流程,提高解决实际问题的能力。记得在实践中...

    PHP完全自学手册前3章

    《PHP完全自学手册》前3章涵盖了PHP编程的基础知识,是初学者入门PHP的重要参考资料。在深入探讨之前,我们先来了解一下PHP是什么。...记得,编程是一个持续学习的过程,不断练习和探索,你将成为一名熟练的PHP开发者。

    基于PHP的Mylog逍遥坊php博客日志系统源码.zip

    PHP以其开源、跨平台和丰富的扩展库而闻名,使得开发者可以快速构建动态网站和应用程序。该博客系统可能利用了PHP的特性,如MVC(模型-视图-控制器)架构模式,使得代码结构清晰,易于维护和扩展。 【标签】"PHP...

    初学PHP的爱好者更适用

    同时,不断探索和研究开源项目,参与社区讨论,将加速你的学习进度。 总的来说,对于初学PHP的爱好者来说,这个资源包提供了全面而实用的学习材料。从基础语法到高级特性的应用,通过深入学习和实践,你将能够熟练...

    PHP下载站

    在构建一个PHP下载站的过程中,新手开发者可能会遇到各种挑战,但这个资源包“CR_downloadPHP”提供了一套全面的学习材料,旨在帮助初学者快速掌握PHP编程,并...在实际操作过程中,不断探索和解决问题将加速学习过程。

    php+mysql网站开发项目式教程

    - 数据缓存:探索如何使用PHP的缓存技术,如memcached或APC,提高网站性能。 4. Web应用框架: - Laravel或Symfony:了解这些流行的PHP框架,它们提供了一种组织代码结构和自动化任务的方式,加速开发进程。 - ...

Global site tag (gtag.js) - Google Analytics