请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

亿仁网

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 4152|回复: 0

LNMP 性能优化之 PHP 性能优化

[复制链接]
  • TA的每日心情
    奋斗
    2019-3-14 22:24
  • 签到天数: 160 天

    [LV.7]常住居民III

    1074

    主题

    1139

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    18046
     楼主| 发表于 2019-11-12 22:06:48 | 显示全部楼层 |阅读模式

    PHP 做一门弱类型动态语言,在上手容易和开发快速同时,也会导致一些新手写出不规范的代码。比如在递归当中连接数据库读取数据;一次性从文件中读取大量的数据,处理完后却不主动释放内存;在遍历和循环中重复计算某个变量等等;数组的键没有加引号导致先查找常量集,都会导致 PHP 程序性能下降。

    PHP 作为一门 Web 后端脚本语言,好处是能够快速实现 Web Application 所需功能,而且容易部署。缺点就是相对于强类型静态语言如 Java/C/C++ 来说,PHP 的性能较差,在实现计算密集型的业务时没有任何优势。同时也由于 PHP 是同步阻塞的 IO 模型,在高并发请求的场景下容易遇到瓶颈,需要通过 PHP 相关扩展来解决相关技术难题。

    PHP 作为一门胶水语言,势必会连接各种各样服务。常见的服务如:MySQL、Redis、MongoDB 等数据库,C/C++、GO、Java 等语言编写的后端服务。倘若 PHP 所连接服务不稳定,势必也会对 PHP 造成一定的性能影响。

    在某些情况,某个 PHP 程序或某段 PHP 代码莫名其妙地出现相当耗时的情况,不知道是 PHP 本身出现了问题,还是所用的框架出现了问题,亦或是 PHP 周边甚至是硬件的问题。这个时候就需要通过工具进行排查。常用的工具有:PHP-Xhprof、PHP-XDebug。

    PHP 的底层是由 C 语言组成的。每次运行 PHP 的程序,都是需要经过 C 语言遍写的 Zend 引擎来解析 PHP 文件,将其编译成为 Opcodes 后再去执行。就这样一来一回就消耗了不少时间和硬件性能。

    PHP 运行流程

    Scanning(Lexing),将 PHP 代码转换为语言片段(Tokens)。

    Parsing,将 Tokens 转换成简单而有意义的表达式(Expression)。

    Compilation,将表达式编译成 Opocdes。

    Execution,顺次执行 Opcodes,每次一条,从而实现 PHP 脚本的功能。

    (*.php) -> scanner -> (Tokens) -> Parser -> (Expression) -> Compilation -> (Opcodes) -> Execution -> (Output)

    PHP 语言级性能优化

    尽可能地使用内置函数来完成任务

    能使用 PHP 内置方法解决的问题,就不要自己手写代码,一是手写代码一般冗余较多,可读性不佳。二是手写代码需要解析编译为底层代码再执行,没有 PHP 内置函数的性能高。

    for & range() 实现同一功能

    1. <?php

    2. for ($i = 0; $i <1000; $i++) {
    3.         $array1[$i] = $i+1000;
    4. }

    5. range(1000,1999);
    复制代码

    以 foreach、in_array 和 array_merge 实现同一功能对比说明:

    1. <?php

    2. arrayMerged = [];
    3. foreach ($array1 as $value) {
    4.         $arrayMerged[] = $value;
    5. }
    6. foreach ($array2 as $value) {
    7.         if(!in_array($value, $arrayMerged)){
    8.                 $arrayMerged[] = $value;
    9.         }
    10. }

    11. array_merge($array1,$array2);
    复制代码

    以 foreach 和 array_column() 实现同一功能对比说明:

    1. <?php

    2. $usernames = [];
    3. foreach ($array as $key => $value) {
    4.         if(isset($value['username']) && !empty($value['username'])){
    5.                 $usernames[$value['id']] = $value;
    6.         }
    7. }

    8. array_column($array, 'username','id');
    复制代码

    以 foreach 和 array_filter() 实现同一功能对比说明:

    1. <?php

    2. $arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
    3. foreach ($arr as $key => $value) {
    4.         if($key === 'b'){
    5.                 $result[$key] = $value;
    6.         }
    7.         if($value === 4){
    8.                 $result[$key] = $value;
    9.         }
    10. }

    11. array_filter($arr, function($v, $k) {
    12.         return $k == 'b' || $v == 4;
    13. }, ARRAY_FILTER_USE_BOTH)
    复制代码

    从服务器方面进行优化,可以选择将服务器不安装其他后端服务软件,仅仅安装 PHP 以及其必要扩展。使单机的性能全部向 PHP 倾斜。同时也对 PHP 的相关参数进行优化,将 PHP 单机服务器性能最大化。在大数据、高并发的场景下,可以尝试将 PHP 服务器集群化,通过负载均衡,将网络请求分配至不同的 PHP 单机服务器处理。

    造物之前,必先造人。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|亿仁网 ( 粤ICP备16098737  

    GMT+8, 2020-8-3 17:53 , Processed in 0.297985 second(s), 26 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表