PHP使用vld扩展查看opcodes

PHP使用vld扩展查看opcodes

需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode。

下载安装vld扩展

该扩展以收录在 PECL

下载对应的版本安装

修改 php.ini,增加 extension=php_vld.dll

php -m

简单使用vld

代码

<?php
echo 1 + 2;

执行

$ php -dvld.active=1 test.php
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       D:\dev\php\my\test.php
function name:  (null)
number of ops:  2
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  40     0  E >   ECHO                                                     3
         1      > RETURN                                                   1

branch: #  0; line:    40-   40; sop:     0; eop:     1; out0:  -2
path #1: 0,
3
使用vld对比代码执行过程

比如有两个写法

写法一:

<?php
$a = 'a';
$b = 'b';
$c = 'c';

echo $a . $b . $c;

其opcodes为

Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       D:\dev\php\my\test.php
function name:  (null)
number of ops:  7
compiled vars:  !0 = $a, !1 = $b, !2 = $c
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  40     0  E >   ASSIGN                                                   !0, 'a'
  41     1        ASSIGN                                                   !1, 'b'
  42     2        ASSIGN                                                   !2, 'c'
  44     3        CONCAT                                           ~6      !0, !1
         4        CONCAT                                           ~7      ~6, !2
         5        ECHO                                                     ~7
         6      > RETURN                                                   1

branch: #  0; line:    40-   44; sop:     0; eop:     6; out0:  -2
path #1: 0,
abc

写法二:

<?php
$a = 'a';
$b = 'b';
$c = 'c';

echo $a, $b, $c;

其opcodes为

Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       D:\dev\php\my\test.php
function name:  (null)
number of ops:  7
compiled vars:  !0 = $a, !1 = $b, !2 = $c
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  40     0  E >   ASSIGN                                                   !0, 'a'
  41     1        ASSIGN                                                   !1, 'b'
  42     2        ASSIGN                                                   !2, 'c'
  44     3        ECHO                                                     !0
         4        ECHO                                                     !1
         5        ECHO                                                     !2
         6      > RETURN                                                   1

branch: #  0; line:    40-   44; sop:     0; eop:     6; out0:  -2
path #1: 0,
abc

我们知道字符串都是不可变的,针对字符串的操作都是会重新分配新的的内存。显然方法二更合理,这里只是列举简单的例子说明vld在优化代码上的可操作性。

line 为文件行号,此处40是因为前面有注释的代码没拷贝过来。
#* 为 opcode 编号。
!0 编译的变量,也叫 CV,以!开头表示,compiled vars: !0 = $a, !1 = $b, !2 = $c
~6 临时变量,以~开头,比如上面的 ~6, ~7

可以在某个具体的点上使用vld来对比opcodes,找到可以优化的方式。

如何阅读 opcodes 可以看看 https://blog.csdn.net/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_sepvld.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,输出内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值