} } }

    PHP 优化详解

    添加时间:2013-7-19 点击量:

    笔者收集的这些技能起原较广,完全性不克不及包管。 因为数量较多,这些优化技能没有经过测试。请各位看官在应用之前自行测试,毕竟?成果这些技能是否能派上用处,还是须要由PHP地点的独特景象所决意的。


    目次索引



    1. 找到瓶颈(Finding the Bottleneck)

    2. 缓存 (Caching)

    3. 编译 vs. 申明(Compiling vs. Interpreting)

    4. 代码减肥 (Content Reduction)

    5. 多线程与多过程(Multithreading & Multiprocessing)

    6. 字符串(Strings)

    7. 正则表达式(Regular Expressions)

    8. 迭代布局 (Iteration Constructs (for, while))

    9. 选择布局 (Selection Constructs (if, switch))

    10. 函数与参数 (Functions & Parameters)

    11. 面向对象布局 (Object-Oriented Constructs)

    12. Session处理惩罚 (Session Handling)

    13. 类型转换 (Type Casting)

    14. 紧缩(Compression)

    15. 错误处理惩罚(Error Handling)

    16. 声明、定义与局限(Declarations, Definitions, & Scope)

    17. 内存泄漏(Memory Leaks)

    18. 不要反复发明轮子(Don’t Reinvent the Wheel)

    19. 代码优化(Code Optimization)

    20. 应用RAM(Using RAM Instead of DASD)

    21. 应用办事(Using Services (e.g., SQL))

    22. 安装与设备(Installation & Configuration)

    23. 其他(Other)


     

    找到瓶颈(Finding the Bottleneck)


    面对一个机能题目是,第一步永远是找到题目产生的原因,而不是去看技能列表。搞熟悉打听产生瓶颈的原因,找到目标并且实验修复,然后再从头测试。查找瓶颈只是长征的第一步,这里有些常用技能,对最首要的第一步找到瓶颈能有所帮助。



    • 应用监控办法(比如监控宝),进行benchmark和监控,收集,希罕是收集状况瞬息万变,做得好的话5分钟就可以找到瓶颈。

    • 解析代码。必须懂得那项目组代码耗时最多,在这些处所多多存眷。

    • 想找到瓶颈,请搜检每个资料恳求(比如,收集、CPU、内存、共享内存、文件体系、过程经管、收集连接等等……)

    • 先对迭代布局和错杂的代码进行benchmark

    • 在在真实负载下用真实数据进行真实测试,当然,若是可以好用产品办事器。


    缓存 (Caching)


    有些人认为缓存是解决机能题目有效的办法之一,尝尝这些:



    • 应用OPCODE(操纵码)缓存,如许脚本就不会在每次接见时从头编译一次。比如:启用Windows平台上的windows缓存扩大。可以缓存opcode,文件,相对路径,session数据和用户数据。

    • 推敲在多办事器景象下应用分布式缓存

    • 在调用imap_header()之前先调用imap_headers()


    编译 vs. 申明(Compiling vs. Interpreting)


    将PHP源码编译成机械码。动态申明履行同样的编译,但它是按行履行的。编译为opcode是调和选择,它可以将PHP源码翻译为opcode,之后opcode再转为机械码。以下为关于编译与申明的相干技能:



    • 上线之前将PHP代码编译为机械码。opcode缓存尽管并不是好的选择,但依旧比申明型来得强。或者,推敲将PHP代码编译成一个C扩大。

    • PHP的opcode编译器(bcompiler)还不克不及在产品景象中应用,然则开辟者应当存眷http://php.net/manual/en/book.bcompiler.php.


    代码减肥 (Content Reduction)


    越少越块。 这些技能可以帮助削减代码:



    • 每页供给更少的功能

    • 清理网页内容

    • 若是申明型履行,请清理注释和其他空白

    • 削减数据库查询


    多线程与多过程(Multithreading & Multiprocessing)


    由快到慢依次为:



    1. 多线程(单一过程中)

    2. 多过程(比如,pcntl_fork,规划任务)

    3. 单过程(一行又一行)


    PHP不支撑多线程,然则可以用C写多线程的PHP扩大。有一些办法可以应用多过程或模仿多过程,但支撑的并不是很好,没准儿比单过程还慢。


    字符串(Strings)


    字符串处理惩罚,是大多半编程说话中最常用的操纵之一。这里有些技能可以帮我们让字符串处理惩罚速度更快一些:



    • PHP的连接运算(点运算),是快的链接体式格式

    • 避免在print中链接字符串,用逗号分别后用ECHO

    • 尽可能应用str_前缀的字符串函数调换正则表达式

    • pos()比preg_mach()和ereg()都快

    • 有人说单引号包裹字符串比双引号更快,有人说没有差别。当然,若是想在字符串中引用变量,单引号没戏。

    • 若是想断定字符串长度是否小于某值(比如5),请应用isset(¥s[4])<5。

    • 如需将多个小字符串连接成一个大字符串,试着先开启ob_start输出缓存,再用echo输出到缓冲区,完成后应用ob_get_contents读取字符串


    正则表达式(Regular Expressions)


    正则表达式为们带来了灵活多样的斗劲与查找字符串的办法,单他的机能开销却实在不低



    • 尽可能应用STR_前缀的字符串处理惩罚函数庖代正则表达式

    • 应用[aeiou]的不是(a|e|i|o|u)

    • 正则表达式越简单速度越快

    • 尽可能不要设置PCRE_DOTALL润饰符

    • 用^.庖代.

    • 简化正则表达式。(比如应用a庖代(a+)


    迭代布局 (Iteration Constructs (for, while))


    迭代(反复,轮回)是最根蒂根基的布局化编程办法,很难想像有不应用它的法度。这里有些技能,帮助我们改进迭代布局的机能:



    • 尽可能讲代码移出到轮回外(函数调用、SQL查询等等……)

    • 应用i=maxval;while(i–)庖代for(i=0;i<maxval;i++),如许可以削减一个操纵,若是maxval是一个函数调用就更明显了。

    • 应用foreach迭代凑集与数组


    选择布局 (Selection Constructs (if, switch))


    与迭代布局雷同,选择布局也是最根蒂根基的布局化变成办法。以下技能或许能改良机能:



    • switches和else-if中,应当将比来常呈现true的列在前面,较少呈现true的请靠后

    • 有人说if-else比swtich/case快,当然,有人否决。

    • 用elseif调换else if.


    函数与参数 (Functions & Parameters)


    将函数的代码分化成小函数代码可以打消冗余,让代码具有可读性,但价格是什么?这里有些技能,以帮助更好的应用函数:



    • 引用传递出对象和数组,而不是传值

    • 若是只在一个处所应用,应用内联。若是在多个处所调用,推敲内联,但请重视可保护性

    • 懂得你所用函数的错杂度。比如similar_text()为O(N^3),这意味着字符串长度增长一倍,处理惩罚时候将增长8倍

    • 不要经由过程“返回引用”来提拔机能,引擎会主动优化它。

    • 以常规体式格式调用函数,而不是应用call_user_func_array()或eval()


    面向对象布局 (Object-Oriented Constructs)


    PHP的面向对象特点,可能会影响到机能。以下提示可以帮助我们尽量削减这种影响:



    • 不是一切都须要面向对象, 机能的丧失可能会跨越其长处本身

    • 创建对象斗劲慢

    • 若是可以,尽可能时辰用数组而不是对象

    • 若是一个办法可以静态化,请静态声明

    • 函数调用比派生类办法调用要快,派生类办法调用比基类调用要快

    • 推敲将基类中最常用的代码复制到派生类中,但要重视保护性隐患

    • 避免应用原生的getters与setters。若是不须要他们,请删除并且属性公开

    • 创建错杂的PHP类时,推敲应用单件模式


    Session处理惩罚 (Session Handling)


    创建sessions有很多益处,但有时会产生没须要的机能开支。以下技能可以帮助我们程度削减机能开支:



    • 不要应用auto_start

    • 不要启用use_trans_sid

    • 将session_cache_limited设置为private_no_expire

    • 为虚拟主机(vhost)中的每个用户分派本身的目次

    • 应用基于内存的session处理惩罚,而不是基于文件的session处理惩罚


    类型转换 (Type Casting)


    从一种类型转换为另一种类型须要本钱


    紧缩(Compression)


    在传输前,紧缩文本和数据:



    • 应用ob_start()在代码肇端处

    • 应用ob_gzhandler()可以提速,然则重视CPU开支

    • Apache的mod_gzip模块可以即使紧缩


    错误处理惩罚(Error Handling)


    错误处理惩罚影响机能。我们能做的是:



    • 记录错误日记,别再应用“@”按捺错误呈报,按捺对机能一样有影响

    • 不要只搜检错误日记,警告日记一样须要处理惩罚


    声明、定义与局限(Declarations, Definitions, & Scope)


    创建一个变量、数组或者对象,对机能都有影响:



    • 有人说,声明和应用全局变量/对象,比局部变量/对象要快,有人否决。请测试再决意。

    • 在应用变量前声明所有变量,不要声明不应用的变量

    • 在轮回中尽可能应用¥a[],避免应用¥a=array(…)


    内存泄漏(Memory Leaks)


    若是内存分派后不开释,这绝对是个题目:



    • 对峙开释资料,不要指望自带/主动的垃圾收受接管

    • 应用完后尽量刊出(unset)变量,尤其是资料类和大数组类型的

    • 应用完毕就封闭数据库连接

    • 每次应用ob_start(),记得ob_end_flush()或者ob_end_clean()


    不要反复发明轮子(Don’t Reinvent the Wheel)


    为什么要花费时候去解决别人已经解决的题目?



    • 懂得PHP,懂得它的功能和扩大。若是你不知道,可能会无法哄骗一些现成的功能

    • 应用自带的数组和字符串函数,它们绝对是机能好的。

    • 前人发明的轮子,并不料味着在你的景象下吸能是好的,多多测试


    代码优化(Code Optimization)



    • 应用一个opcode optimizer

    • 若是将被申明运行,请精简源码


    应用RAM(Using RAM Instead of DASD)


    RAM比磁盘快很多很多,应用RAM可以提拔一些机能:



    • 移动文件到Ramdisk

    • 应用基于内存的session处理惩罚,而不是基于文件的session处理惩罚


    应用办事(Using Services (e.g., SQL))


    SQL经常被用来接见关系型数据库,但我们的PHP代码可以接见很多不合的办事。下面是一些接见办事是须要紧记的:



    • 不要一遍又一遍地问办事器向东的工作。应用memoization缓存第一次的成果,今后接见直奔缓存;

    • 在SQL中,应用mysql_fetch_assoc()庖代mysql_fetch_array(),可以削减成果集中的整数索引。以字段名接见成果集,而不消索引数字。

    • 对于Oracle数据库,若是没有足够的可用内存,增长oci8.default_prefetch。将oci8.statement_cache_size设置为应用中的语句数

    • 请应用mysqli_fetch_array()调换mysqli_fetch_all(), 除非成果集将发送到其他层进行处理惩罚。


    安装与设备(Installation & Configuration)


    安装与设备PHP时,请推敲机能:



    • 添加更多内存

    • 删除竞争性的应用与办事

    • 只编译所须要用的扩大

    • 将PHP静态编译进APACHE

    • 应用-O3 CFLAGS开启所有编译器优化

    • 只安装所需应用的模块

    • 进级到新版本的次要版本。主板本进级,比及第一次bug修复后再进行,当然,也别等太久

    • 为多CPU景象进行设备

    • 应用 -enable-inline-optimization

    • 设置session.save_handler=mm ,以 -with-mmto编译,应用共享内存

    • 应用RAM disk

    • 封闭resister_global和magic_quotes_

    • 封闭expose_php

    • 封闭 always_populate_raw_post_data 除非你必须应用它

    • 非号令行模式下请封闭register_argc_argv

    • 只在.php文件中应用PHP

    • 优化max_execution_time, max_input_time, memory_limit与output_buffering的参数

    • 将Apache设备文件中allowoverride设置为none提拔文件/目次的接见速度

    • 应用-march, -mcpu, -msse, -mmmx, and -mfpmath=sseto使CPU优化

    • 应用MySQL原生驱动(mysqlnd)调换libmysql、mysqli扩大以及PDO MYSQL驱动

    • 封闭 register_globals、register_long_arrays以及register_argc_argv. 开启auto_globals_jit.


    其他(Other)


    还有些技能斗劲难归类:



    • 应用include()、require(),避免应用include_once()和require_once()

    • 在include()/require()中应用绝对路径

    • 静态HTML被PHP生成的HTML要快

    • 应用ctype_alnum、ctype_alpha以及ctype_digit庖代正则表达式

    • 应用简单的servlets或CGI

    • 代码在产品景象中应用时,尽可能写日记

    • 应用输出缓冲

    • 请应用isset(¥a)庖代斗劲¥a==null;请应用¥a===null庖代is_nul(¥a)

    • 须要脚本开端履行时候,请直接读取¥_SERVER[’REQUEST_TIME’],而不是应用time()

    • 应用echo调换print

    • 应用前自增(++i)庖代后自增(i++),大多半编译器如今都邑优化,然则他们不优化时,请对峙如许的写法。

    • 处理惩罚XML,应用正则表达式庖代DOM或者SAX

    • HASH算法:md4, md5, crc32, crc32b, sha1比其他的散列速度都要快

    • 应用spl_autoload_extensions时,文件扩大名请按最常用–>最不常用的次序,尽量打消掉压根不消的。

    • 应用fsockopen或fopen时,应用IP地址庖代域名;若是只有一个域名,应用gethostbyname()可以获取IP地址。应用cURL速度会更快。

    • 但凡可能,用静态内容庖代动态内容。

    原来,再大的房子,再大的床,没有相爱的人陪伴,都只是冰冷的物质。而如果身边有爱人陪伴,即使房子小,床小,也觉得无关紧要,因为这些物质上面有了爱的温度,成了家的元素。—— 何珞《婚房》#书摘#
    分享到: