1 不要随便就复制变量
有时候为了使 PHP 代码更加整洁,一些 PHP 新手(包括我)会把预定义好的变量复制到一个名字更简短的变量中,其实这样做的结果是增加了一倍的内存消耗,只会使程序更加慢。试想一下,在下面的例子中,如果用户恶意插入 512KB 字节的文字到文本输入框中,这样就会导致 1MB 的内存被消耗!
BAD:
$description = $_POST['description'];
echo $description;
GOOD:
echo $_POST['description'];
2 字符串使用单引号,并且字符串中含有变量的使用单引号字符串链接。
GOOD:
$output = 'This is a plain string';
BAD:
$type = "mixed";
$output = "This is a $type string";
GOOD:
$type = 'mixed';
$output = 'This is a ' . $type .' string';
3 静态成员的调用一定要定义成static类型 foo::bar();效率会提升50-60%
// PHP CODE Highliting for CU by dZ902
效率会提升50-60%
4 使用类常量的好处是: 贴士:PHP 5 新功能,类似于 C++ 的 const。
- 编译时解析,没有额外开销
- 杂凑表更小,所以内部查找更快
- 类常量仅存在于特定「命名空间」,所以杂凑名更短
- 代码更干净,使除错更方便
5 不要调用毫无意义的函数,有对应常量的时候,不要使用函数
php_uname('s') == PHP_OS;
php_version() == PHP_VERSION;
php_sapi_name() == PHP_SAPI;
虽然使用不多,但是效率提升大概在 3500% 左右
6 当记录时间的时候使用$_SERVER['REQUEST_TIME'];不用time();
7 require/include_once 每次被调用的时候都会打开目标文件! require_once()代价昂贵
- 如果用绝对路径的话,PHP 5.2/6.0 不存在这个问题
- 新版的 APC 缓存系统 已经解决这个问题
文件 I/O 增加 => 效率降低
如果需要,可以自行检查文件是否已被 require/include。
include 'file.php' ; // bad approach
incldue './file.php' ; // good
include '/path/to/file.php' ; // ideal
8 加速 pcre 能不用正则就不用正则,仔细看阅读手册的字符串函数
例如: strpbrk() strncasecmp() strpos()/strrpos()/stripos()/strripos()
9 如果需要转换的全是单个字符的时候,用字符串而不是数组来做 strtr:
$addr = strtr ( $addr , "abcd" , "efgh" ); // good
$addr = strtr ( $addr , array( 'a' => 'e' ,
// ...
)); // bad
效率提升十倍
10 不要做无谓的替换: 即使没有替换,str_replace 也会为其参数分配内存。很慢!解决办法:
- 用 strpos 先查找(非常快),看是否需要替换,如果需要,再替换
效率:
- 如果需要替换:效率几乎相等,差别在 0.1% 左右。
- 如果不需要替换:用 strpos 快 200%。
11 善用 strncmp:当需要对比「前 n 个字符」是否一样的时候,用 strncmp/strncasecmp,而不是 substr/strtolower,更不是 PCRE,更千万别提 ereg。strncmp/strncasecmp 效率最高(虽然高得不多)。
12 substr_compare 应该比先 substr 再比较快咯。答案是否定的,除非:- 无视大小写的比较- 比较较大的字符串
13 不要使用常量代替字符串
为什么:
- 需要查询杂凑表两次
- 需要把常量名转换为小写(进行第二次查询的时候)
- 生成 E_NOTICE 警告
- 会建立临时字符串
效率差别:700%。
14 不要把count/strlen/sizeof放到for循环的条件语句中
<?php
for ( $i = 0 , $max = count ( $array ); $i < $max ; ++ $i );
?>
15 PHP 有很多扩展和函数可用,在实现一个功能的之前,应该看看 PHP 是否有了这个功能?是否有更简单的实现?
$filename = "./somepic.gif" ;
$handle = fopen ( $filename , "rb" );
$contents = fread ( $handle , filesize ( $filename ));
fclose ( $handle );
// vs. much simpler
file_get_contents ( './somepic.gif' );
16 关于引用的技巧
引用就是将多个不同的php变量绑定到一个地址,对于大容量参数似乎会节省内存
简化对复杂结构数据的访问
- 优化内存使用
通过修改$str的值道道修改$a值的目的
注意不要错误的使用引用传递,因为php具有写时拷贝的特征,一般不需要改变值的时候不要使用引用传递
http://www.wljcz.com/html/PHPjiaocheng/phpjichu/2010/0319/3068.html
按值传递:函数范围内对值的任何改变在函数外部都会被忽略
按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。
按引用传递则不需要复制值,对于性能提高很有好处。
17 注销那些不用的变量尤其是大数组,以便释放内存。
使用unset:
对于PHP的局部变量,劈如自定义函数和类方法中的过程变量,完全无需使用 unset,越 unset 占用内存就越多,应该是PHP在运行过程中,局部变量在使用过后会立即注销,所以如果再注销的话,完全是多了步骤,起了反作用。
而对于全局变量,PHP只会在当前PHP文件的运行结束后才会释放此部分内存,在运行过程中是不释放的,所以应该适时的注销相关不再用的全局变量。
对于已经实例化的类的属性,注销掉也是可以释放内存的,因为这也是在整个过程中生效,当然如果可以,你可以直接注销实例化的变量。
对于注销数组还可以使用$a = array();
避免溢出,释放内存,也是优化程序
http://blog.zol.com.cn/781/article_780182.html
18 尽量避免使用__get,__set,__autoload。
19 str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。
20 如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。 ?
21 打开apache的mod_deflate模块,启动压缩功能
http://yangsiwei.com/add-mod_deflate-module-to-apache2/comment-page-1
22 数据库连接当使用完毕时应关掉。这个是需要在不同的情况下有不同的考虑的
链接使用:mysql_connent, 关闭使用:mysql_close
http://bbs.chinaunix.net/viewthread.php?tid=785198
具体的数据库持久连结的概念在php手册里有很详细的介绍
方案一:
mysql.open();
mysql.insert('sql1');
mysql.insert('sql2');
:
mysql.insert('sqln');
mysql.close();
方案二:
mysql.open();
mysql.insert('sql1');
mysql.close();
mysql.open();
mysql.insert('sql2');
mysql.close();
:
mysql.open();
mysql.insert('sqln');
mysql.close();
肯定是第一个效率高的。
从最简单的来说,连接数据库是要有时间的,多次的连接效率肯定慢。
而且要是是远程数据库的话,你这种不停的要求连接的语句会带宽占用时间也大。
第二种方法应该是防止有的线程占线的,就是连接后有大段不需要连数据库的逻辑执行的程序,但像楼主这样写的连续执行sql的都不用多说了,肯定是第一个好。
mysql Resource id概念 ?
数据库的连接将保持开放状态,直到所有对它的引用被释放。如果在主脚本的顶端打开连接,并将其句柄存储在一个全局变量中,那么该连接将一直处于开放状态,直到脚本结束,或者直到 $dbh 变量被设为 null。如果在一个函数中打开连接,并且只将句柄存储在一个本地变量中,那么当函数返回时,连接将被关闭。这些语义对于 PHP 中的任何对象都是一样的,没有什么特别的地方。
23 $row[‘id’]的效率是$row[id]的7倍
24 错误消息代价昂贵
25 在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。
http://www.huison.cn/blog/article.asp?id=230
26 递增一个全局变量要比递增一个局部变量慢2倍
27 递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。
28 仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。
29 方法调用看来与类中定义的方法的数量无关,因为我(在测试方法之前和之后都)添加了10个方法,但性能上没有变化。
30 派生类中的方法运行起来要快于在基类中定义的同样的方法。
31 用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会。当然,只有当你不需要在字符串中包含变量时才可以这么做。
32 Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本
33 除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。
34 尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码(OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。
35 当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。
Ex.(举例如下)
if (strlen($foo) < 5) { echo "Foo is too short"; }
vs.(与下面的技巧做比较)
if (!isset($foo{5})) { echo "Foo is too short"; }
调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。
36 当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商(ISPs)和服务器。
37 并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
38 并非要用类实现所有的数据结构,数组也很有用。
39 不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
40 当你需要时,你总能把代码分解成方法。
41 尽量采用大量的PHP内置函数。
42 如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们
43 评估检验(profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。
44 mod_gzip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80%。
http://www.wangchao.net.cn/bbsdetail_1754024.html 压缩页面
45 Excellent Article (http://phplens.com/lens/php-book/optimizing-debugging-php.php )about optimizing php by John Lim 另一篇优化PHP的精彩文章,由John Lim撰写。
参考 :http://www.cnblogs.com/xin478/archive/2008/09/10/1288657.html
46 线程池的介绍及简单实现 http://www.wangchao.net.cn/bbsdetail_1754028.html
http://www.ajaxstu.com/PHPbiancheng/183975.html 针对php,
http://home.phpchina.com/space.php?uid=92493&do=blog&id=182169 深入研究线程池
php在连接mysql数据库的时候我们可以采用临时的连接,当然我们也可以采用永久连接,采用永久连接的时候因为有一次连接的开销,所以时间就大大的减少了,但是我们才用永久连接的时候一定要注意一下的一些问题?
永久连接在数据库崩溃或者别的原因的话,永久连接不知道数据库已经关闭,然后在去连接数据库的时候就会出错,解决的办法只有写一个方法定时的检查数据库的状态,如果出错就从新连接。
php与mysql数据库的连接的永久连接是创建一些线程,然后每一次都连接的时候就在线程池中找到一个闲置的连接,然后返回,但是apache服务器只支持一定数目的线程,当服务器的访问量特别大的时候,数据库的连接线程可能就会超出apache服务器支持的数目,这样可能回造成服务器的崩溃,所以我门要在apache服务器的配制文件中修改线程的最大数目,来保证服务器的稳定。
当有多个用户同时使用一个永久连接的时候,可能回出现数据的错误,或者是读脏数据等其他的情况,这也是我们经常要注意的问题!
问题:什么时候使用线程池
47 php效率总结
1),在函数中,传递数组时
使用 return 比使用 global 要高效
比如
function userloginfo($usertemp){
$detail=explode("|",$usertemp);
return $detail;
}
$login=userloginfo($userdb);
比
function userloginfo($usertemp){
global $detail;
$detail=explode("|",$usertemp);
}
userloginfo($userdb);
要高效
2),(这个代码用于得到程序目录对应的网址,推荐使用)
$urlarray=explode('/',$HTTP_SERVER_VARS['REQUEST_URI']);
$urlcount=count($urlarray);
unset($urlarray[$urlcount-1]);
$ofstarurl='http://'.$HTTP_SERVER_VARS['HTTP_HOST'].implode('/',$urlarray);
这段代码比
$pre_urlarray=explode('/',$HTTP_SERVER_VARS['HTTP_REFERER']);
$pre_url=array_pop($pre_urlarray);
要高效
3),在循环中判断时,数值判断使用恒等要比等于高效
$a=2;$b=2;
比如
if($a==$b)$c=$a;
比
if($a===$b)$c=$a;
高效
4),mysql 查询时尽量使用where in 少用 limit
limit查多记录的前几条, 速度很快, 但是查询最面几条就会慢
使用in .在查询连续性记录,非常快, 非连续性记录第一次运行会稍微慢一点,但是之后将比较快!
5),NT 服务器数据操作稳定性不及unix/linux
6),输出前使用尽量使用 ob_start(); 可以加快输出速度,适用NT或nuli/linux,对unlix类服务器 如果使用 ob_start('ob_gzhandler');输出效率将更高
7),判断的时候尽量使用if($a==他的值) 否定的时候尽量使用if(empty($a)),因为这样程序运行更快速
8),使用不等时 != 与 <> 效率相当
9), 个人经验得 使用 $a="11111111111111"; 的效率和 $a='11111111111111'; 相当.并不象书本说的相差很大
10), 使用规范的SQL语句, 会有利于MySQL的解析
11),使用
if($online){
$online1=$online;
setcookie('online1',$online,$cookietime,$ckpath,$ckdomain,$secure);
}
COOKIE 将马上生效
使用
if($online)
setcookie('online1',$online,$cookietime,$ckpath,$ckdomain,$secure);
COOKIE 需要再刷新一次才能生效
12),使用
$handle=fopen($filename,wb);
flock($handle,LOCK_SH);
$filedata=fread($handle,filesize($filename));
fclose($handle);
比
file($filename);
无论在速度还是稳定上都要优秀
13),截断字符串优化函数(可避免?字符出现)
function substrs($content,$length) {
if(strlen($content)>$length){
$num=0;
for($i=0;$i<$length-3;$i++) {
if(ord($content[$i])>127)$num++;
}
$num%2==1 ? $content=substr($content,0,$length-4):$content=substr($content,0,$length-3);
$content.=' ...';
}
return $content;
}
比如$newarray[1]=substrs($newarray[1],25);
14),程序中屏蔽大小写
for ($asc=65;$asc<=90;$asc++)
{ //strtolower() 此函数在一些服务器会产生乱码!
if (strrpos($regname,chr($asc))!==false)
{
$error="为了避免用户名混乱,用户名中禁止使用大写字母,请使用小写字母";
$reg_check=0;
}
}
15),不使用 file();和不使用 fget();(不稳定或速度慢) 取一数组函数
function openfile($filename,$method="rb")
{
$handle=@fopen($filename,$method);
@flock($handle,LOCK_SH);
@$filedata=fread($handle,filesize($filename));
@fclose($handle);
$filedata=str_replace("\n","\n<ofstar:>",$filedata);
$filedb=explode("<ofstar:>",$filedata);
//array_pop($filedb);
$count=count($filedb);
if($filedb[$count-1]==''){unset($filedb[$count-1]);}
return $filedb;
}
//这个函数虽然代码比较多,不过在速度和稳定性上优势很大!
48 php autoload与include性能比较
http://www.xue163.com/html/2009430/1322206.html
49 使用XDebug对php进行性能分析
http://www.cnblogs.com/afritxia2008/archive/2010/06/26/1765955.html
50 三款免费的php加速器:apc、eAccelerator、XCache比较
http://www.vpser.net/opt/apc-eaccelerator-xcache.html
51 ab windows下的操作 http://server.csdn.net/n/20090523/1789.html
52 mysql 慢查询分析 http://www.iteye.com/wiki/topic/543075
http://www.iteye.com/topic/242516
http://msnvip.iteye.com/blog/543075
http://thomaslee007.iteye.com/blog/231611
54 异步IO,APC,IO完成端口,线程池与高性能服务器系列文章 http://hi.baidu.com/027fs/blog/item/a331d5222e6a61f9d7cae2b6.html
参考资料
Excellent Article (http://phplens.com/lens/php-book/optimizing-debugging-php.php )about optimizing php by John Lim 另一篇优化PHP的精彩文章,由John Lim撰写。
http://ilia.ws
Ilia 的个人网站,Blog,他参与的开发以及出版的一些稿物链接等等。 Ilia Alshanetsky (佩服之至) 在多个 PHP 会议上的演讲,主要是各类提高 PHP 性能的技巧。为求精准,很多部分都有详细的效率数据,以及对应的版本等等。如果需要看原文档,请到文末「参考资料」部分
http://ez.no
eZ components 官方网站,eZ comp 是针对 PHP5 的开源通用库,以效率为己任,Ilia 也参与了开发。
http://phparch.com
php|architect,不错的 php 出版商/培训组织。买不起或者买不到的话,网上可以下到很多经典的盗版。
http://talks.php.net
PHP 会议上的演讲合集,现在还不是很丰富,不过内容都是让人一看就容易废寝忘食的好东东,推荐早上睡眼朦胧的时候或者吃完午饭仔细研究,否则你会忘记吃饭和睡觉的!
http://www.westphp.com/bbs/archiver/tid-1134.html 新的40条有点不同
做好性能测试应该掌握的内容 http://www.cnblogs.com/jackei/archive/2008/06/27/1231307.html
一个很好的blog,里面有使用nginx的负载均衡等很多增加性能方面的 http://www.phpabc.cn/