首页 > IT职业 > IT生活 > 性能优化之PHP优化
PHP 性能问题的解决方向
PHP语言级别的性能优化 =》 PHP周边问题的性能优化 =》 PHP语言自身分析、优化 1). ab 是由 Apache 提供的压力测试软件,安装 apache 服务器时会自带该压力测试软件
2). 基本使用[Linux 平台]
./ab -n1000 -c100 http://www.baidu.com/
# -n 请求数
# -c 并发数
# url 目标压力测试地址 3). 参考项
# 每秒接收请求数 =》 尽可能大
Requests per second (mean)
# 每一个请求的耗时情况 =》 尽可能小
Time per request (mean, across all concurrent requests) 1). 性能问题:自身代码冗余较多,可读性不佳,并且性能低。
2). 为什么性能低:PHP 代码需要编译解释为底层语言,这一过程每次请求都会处理一遍,开销大。
3). 好的方法:多实用 PHP 内置变量、常量、函数。
.php文件 =>[zend引擎 Scanner]=> zend exprs => [Parser] => Opcodes(要被执行的代码) => [Exec] => Output 【补充】目前很多 php 的缓存服务使用的都是 opcode,节省了扫描和解析的过程,提升速度。
1). array_key_exists() vs isset()
php 执行效率上: isset > array_key_exists
二、语言级性能优化(二)PHP 提供的魔法函数,性能不佳
为了给 PHP 程序员省事,PHP 语言为你做了很多
尽可能规避使用 PHP 魔法函数
【补充】:命令行模式查看 php 文件执行耗时
# time命令
time php test.php
# 输出结果
real
user => 主要参考的耗时
sys @
PHP 提供的错误已支付只是为了方便懒人
@ 的实际逻辑:在代码开始前、结束后,增加 Opcode,忽略报错
vld - PHP Opcode 查看扩展
1)测试文件at.php
//at.php
file_get_contens('xxx'); // xxx文件不存在 2)使用 vld 扩展执行at.php,查看执行过程的完整 Opcode
php -dvld.active=1 -dvld.execute=0 at.php
# 不加@错误抑制符时Opcode的执行情况
SEND_VAL
DO_FCALL
RETURN
# 加@错误抑制符时Opcode的执行情况
BEGIN_SILENCE
SEND_VAL
DO_FCALL
END_SILENCE
RETURN 可以使用 try throw 方式进行错误控制
PHP 有内存回收机制保底,但也要小心使用内存
利用 unset()及时释放不使用的内存[注:unset()出现注销不掉的情况]
正则表达式的回溯开销比较大,"没有金刚钻别揽瓷器活"
利用字符串处理函数,实现相同逻辑
循环内的计算式将会被重复计算
$str = "hello world";
for ($i=0; $i PHP 不适合密集型运算的场景[大批量日志分析、大批量数据处理]
PHP 语言特性决定了 PHP 不适合做大数据量运算。[需要解析成 C 语言进行运算,C 语言可能几行代码就实现的计算,php 可能需要很多行代码才能实现]
适合衔接 Webserver 与后端服务、UI 呈现[纽带]
PHP 会将没有引号的键值当做常量,产生查找常量的开销
【补充】:
# 将后台运行的任务放到前台终端运行
fg
# 相关命令: jobs bg fg
# 将任务号为1的任务从后台执行转换到其那台执行。
fg 1
# 执行上述命令后,命令行窗口将显示如下信息
find / -name password define('key', 'imooc');
$array = array(
'key' => 'hello world!',
'imooc' => 'http://www.imooc.com/'
);
echo $array["key"] . 'n'; // 输出 hello world
echo $array[key] . 'n'; // 输出 http://www.imooc.com/ 【说明】:
当时用$array[key]时,程序也把 key 作为常量去查找,当查找到时,获取到常量的值;当没查找到时,再到数组内部,将其作为键 key 字符串进行解析
严格使用引号作为键值
三、PHP 周边问题的分析与阐述Linux 运行环境
文件存储[磁盘]
数据库[mysql]
缓存[硬件的内存、php 缓存技术:memcache redis]
网络
同一台服务器 => 数据库优化 决定时间性能
1) 常见 PHP 场景的开销次序:
读写磁盘、 读写数据库、读写内存、读写网络数据
2) 时间开销:
读写内存 3) 总结:
尽可能多的使用读写数据库、读写内存,尽量规避操作磁盘和操作网络数据。
网络请求的坑:
1.对方接口的不确定因素 2.网络稳定性
如何优化网络请求?
1.设置超时时间
a) 连接超时
b) 读超时
c) 写超时
2.将串行请求并行化
a) 使用 curlmulti*() => 最简单,但是并不是最好用
b) 使用 swoole 扩展 => 效果更好
使用 Gzip 即可。
2)利与弊:
利: 利于我们的数据输出,Client 端能更快获取数据
弊: 额外的 CPU 开销
多次请求,内容不变的情况。[模板缓存]
|---Cached----/
/ |
.php Cache -> No Cache
/ |
|---------/ 串行:
process1[客户端] process2[web server] process3[php] process4[mysql或缓存] 重叠时间窗口:
process1
process2
process3
process4 使用前提:后一个任务不强依赖于前一个任务的输出或返回。
x.php x.php
| |
process1 process1
| |---------process2
process2 process3 |
| | 使用前提:后一个任务不强依赖于前一个任务的输出或返回。
四、具体的性能分析工具: XHProf [源自 Facebook 的 PHP 性能分析工具]
实践: 分析 Wordpress 程序,做优化
1) 检查 xhprof 工具是否安装成功
php --ri xhprof
//输出
xhprof
xhprof => 0.9.2
CPU num => 1 2) 在 wordpress 代码中[index.php 文件]
1.在起始位置添加`xhprof_enable()`进行开启xhprof
2.在执行结束位置添加`xhprof_disable()`返回性能分析数据
3.添加xhprof的两个lib文件 wordpress/index.php 代码
xhprof_enable();
define('WP_USE_THEMES', true);
require(dirname(__FILE__) . '/wp-blog-header.php');
$data = xhprof_disable();
include_once "/var/www/html/xhprof_lib/utils/xhprof_lib.php";
include_once "/var/www/html/xhprof_lib/utils/xhprof_runs.php";
$objXhprofRun = new XHProfRuns_Default();
$run_id = $objXhprofRun->save_run($data, "test");
var_dump($run_id); 3) wordpress 同级目录下的 xhp 目录
callgraph.php
css/
docs/
index.php
jquery/
js/
typeahead.php 4)浏览器访问 xhp/index.php
查看列表形式的性能分析 =》 View Full Callgraph =》 查看图形流程分析[查看耗时最长的文件和方法]=>MO::import_from_reader| MO::make_entry 5)查找最需要优化的文件
grep 'import_from_reader' ./ -r
6)主要耗时点:MO::make_entry() -- 执行的是多语言支持的功能
优化方式:直接注释掉调用的相关代码
【补充】:MO和PO都是 PHP 处理多语言程序的语言包
7)优化结果:
让程序不再是只有一个或一处相互关联的高消耗代码点。
XHProf -- PHP性能分析工具
ab -- 压力测试
vld -- opcode代码分析
五、PHP 性能瓶颈终极办法APC
官方地址:前往
已不再更新。
【补充】:pecl.php.net是php扩展的官方维护站点。了解并使用类似APC的opcode 缓存扩展?
yac - 通过共享内存来缓存用户数据,用于代替APC和本地memcached的方案。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1542/viewspace-2804284/ ,如需转载,请注明出处,否则将追究法律责任。