PHP使用vld扩展查看opcodes
需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode。
下载安装vld扩展
该扩展以收录在 PECL
下载对应的版本安装
修改 php.ini,增加extension=php_vld.dll
php -m
简单使用vld
代码
<?phpecho 1 + 2;
执行
$ php -dvld.active=1 test.phpFinding entry pointsBranch analysis from position: 01 jumps found. (Code = 62) Position 1 = -2filename: D:\dev\php\my\test.phpfunction name: (null)number of ops: 2compiled vars: noneline#* E I O op fetchext return operands-------------------------------------------------------------------------------------400 E > ECHO 31> RETURN 1branch: # 0; line: 40- 40; sop:0; eop:1; out0: -2path #1: 0,3
使用vld对比代码执行过程
比如有两个写法
写法一:
<?php$a = 'a';$b = 'b';$c = 'c';echo $a . $b . $c;
其opcodes为
Finding entry pointsBranch analysis from position: 01 jumps found. (Code = 62) Position 1 = -2filename: D:\dev\php\my\test.phpfunction name: (null)number of ops: 7compiled vars: !0 = $a, !1 = $b, !2 = $cline#* E I O op fetchext return operands-------------------------------------------------------------------------------------400 E > ASSIGN !0, 'a'411 ASSIGN !1, 'b'422 ASSIGN !2, 'c'443 CONCAT ~6!0, !14 CONCAT ~7~6, !25 ECHO ~76> RETURN 1branch: # 0; line: 40- 44; sop:0; eop:6; out0: -2path #1: 0,abc
写法二:
<?php$a = 'a';$b = 'b';$c = 'c';echo $a, $b, $c;
其opcodes为
Finding entry pointsBranch analysis from position: 01 jumps found. (Code = 62) Position 1 = -2filename: D:\dev\php\my\test.phpfunction name: (null)number of ops: 7compiled vars: !0 = $a, !1 = $b, !2 = $cline#* E I O op fetchext return operands-------------------------------------------------------------------------------------400 E > ASSIGN !0, 'a'411 ASSIGN !1, 'b'422 ASSIGN !2, 'c'443 ECHO !04 ECHO !15 ECHO !26> RETURN 1branch: # 0; line: 40- 44; sop:0; eop:6; out0: -2path #1: 0,abc
我们知道字符串都是不可变的,针对字符串的操作都是会重新分配新的的内存。显然方法二更合理,这里只是列举简单的例子说明vld在优化代码上的可操作性。
line
为文件行号,此处40是因为前面有注释的代码没拷贝过来。
#*
为 opcode 编号。
!0
编译的变量,也叫 CV,以!
开头表示,compiled vars: !0 = $a, !1 = $b, !2 = $c
~6
临时变量,以~
开头,比如上面的~6, ~7
。
可以在某个具体的点上使用vld来对比opcodes,找到可以优化的方式。
如何阅读 opcodes 可以看看 /raoxiaoya/article/details/98941938
vld的配置
vld.active
是否在执行PHP时激活VLD挂钩,默认为0,表示禁用。可以使用-dvld.active=1启用。vld.execute=0
只想查看opcodes,不想真的运行代码。vld.format
是否以自定义的格式显示,默认为0,表示否。可以使用vld.format=1
,表示以自己定义的格式显示。这里自定义的格式输出是以vld.col_sep
指定的参数间隔。vld.col_sep
在vld.format
参数启用时此函数才会有效,默认为 “\t”。vld.skip_prepend
是否跳过php.ini配置文件中auto_prepend_file指定的文件, 默认为0,即不跳过包含的文件,显示这些包含的文件中的代码所生成的中间代码。此参数生效有一个前提条件:vld.execute=0
。vld.verbosity
是否显示更详细的信息,默认为1,其值可以为0,1,2,3 其实比0小的也可以,只是效果和0一样,比如0.1之类,但是负数除外,负数和效果和3的效果一样 比3大的值也是可以的,只是效果和3一样,3是最新详细的。vld.save_paths
控制是否输出文件,默认为0,表示不输出文件。vld.save_dir
指定文件输出的路径,默认路径为/tmp。vld.dump_paths
控制输出的内容,现在只有0和1两种情况,默认为1,输出内容。
如果觉得《PHP使用vld扩展查看opcodes》对你有帮助,请点赞、收藏,并留下你的观点哦!