概述:今天在看鸟哥的博客:PHP 8新特性之JIT简介(大家有兴趣可以直接点击链接查看)看到了一个之前一直有听过的opcode但是没有深入了解的扩展,花了2个小时,查阅了些资料,和圈内人稍微探讨了下,对其认识做个记录。
1.什么是opcode?
opcode:解释器分析代码之后,生成可以直接运行的中间代码,就称做操作码opcode
这个是我在网上找的比较笼统的解释,为了能够更加深入了解它,我们认识下php的生命周期:
如图所示:
- .php - Zend引擎从文件当中读取文件
- Lexicon scan- 扫描词典和表达式(将PHP代码转换为语言片段(Tokens)
- Parse - 将Tokens转换成简单而有意义的表达式
- Create Opcode - 将表达式编译成Opocdes,即创建要执行的计算机代码(称为Opcode)
- Process Opcode - 最后执行Opcode,顺次执行Opcodes
我这边不再去追溯opcode的前身,由什么衍变而来,专注于它给我们做了什么??
2.opcode在php7.1版本之后,为我们做了什么?
Opcode cache:目地是避免重复编译,减少CPU和内存开销
这边直接附上图来解释:
简单来说:
-
每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重行生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快。
所以我们在项目运行中开启这个扩展,可以在运行速度上有着明显的提升,解决了php不常驻内存,每次都需要重新加载执行的缺陷。 -
这里我们需要了解一个基于php中master-worker进程模型的swoole进程模型Swoole进程模型概述,如果不了解可以直接去前面看我写的博客,这个框架是常驻内存的,所以使用这个框架就没什么必要去开启这个扩展了。
-
当然,在开发当中不适合开启,因为每次都需要重新加载执行的缺陷。(这边有待考究,不知道会不会识别出加载的文件不一致,使缓存失效进而重新预编译文件)
下面讲的是JIT,貌似和上面讲的没什么实际关联,但是摘自鸟哥博客一句话:JIT不是原来Opcache优化的替代,是增强。
下面大致谈下我对jit的认识,先上图,后续我再弥补下对这个认识需要的一些概念知识:
左图是PHP8之前的Opcache流程示意图, 右图是PHP8中的Opcache示意图。(这边图片的引用也是摘自鸟哥上述链接博文中)
我们注意到,在右下角多了一个JIT Compiler,他在opcode执行后生成了机器码,交给cpu直接运行,并且由opcode实现了,机器码的缓存。
所以以后php可以多做一些cpu密集型的任务。也期待PHP带来新的突破
这边涉及到概念的知识,在编译语言中,存在着两种编译技术:
1.一种是aot,也就是ahead of time,事前编译,如golang,c,c++,运行之前就编译成机器码,所以这些语言是直接在cpuy上运行,没有虚拟机
2.一种是jit,也就是just in time,也就是执行到时候。跟java,会把字节码编译成机器码
这边再附上和朋友探讨的话,因为对java了解的还不是很深,处于刚学习状态,就先不论对错了