认识PHP 7虚拟机(4)

类的延迟绑定

简单地说,类A继承类B,类B最好先于类A被定义。

class Bar { }
class Foo extends Bar { }

number of ops:  4
compiled vars:  none
line     # E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NOP
   3     1        NOP
         2        NOP
         3      > RETURN    

从生成的OPCode可以看出,上述PHP代码在运行时,执行引擎不需要做任何操作。类的定义是比较耗性能的工作,例如解析类的继承关系,将父类的方法/属性添加进来,但编译器已经做完了这些繁重的工作。

如果类A先于类B被定义:

class Foo extends Bar { }
class Bar { }

number of ops:  4
compiled vars:  none
line     # E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   FETCH_CLASS                                   0  :0      'Bar'
         1        DECLARE_INHERITED_CLASS                                  '%00foo%2Fhome%2Froketyyang%2Ftest.php0x7fb192b7101f', 'foo'
   3     2        NOP
         3      > RETURN                                                   1

这里定义了Foo继承自Bar,但当编译器读取到Foo的定义时,编译器并不知道任何关于Bar的情况,所以编译器就生成相应的OPCode,使其定义延迟到执行时。在一些其他的动态类型的语言中,可能会产生错误:Parse error : class not found。

除了类的延迟绑定,像接口、traits都存在延迟绑定耗性能的问题。

对于定位PHP性能问题,通常都是先用xhprof或xdebug profile进行定位,需要通过查看OPCode定位性能问题的场景还是比较少的。

总结

希望通过这篇文章,能让你了解到PHP虚拟机大致是如何工作的。具体opcode的执行,以及函数调用涉及到的上下文切换。

联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2024

备案号:京ICP备15003423号-3