什么是opcode

opcode(operate code)是计算机指令中的一部分,用于指定要执行的操作,指令的格式和规范由处理器的指定规范指定

opcode是一种php脚本编译后的中间语言,就像java的ByteCode,或者.NET的MSL

为什么要使用opcode缓存

opcode cache的目的是避免重复编译,减少CPU和内存开销的。如果动态内容的性能瓶颈不在于CPU和内容,而在于IO操作,比如数据库查询带来的IO开销,这个时候opcode cache的性能提升是非常有局限的。无论如何既然opcode cache 可以降低cpu和内存的开销,这当然是好事了

目前PHP中常见的opcode cahce模块如下

APC

Optimizer+(目前已开源并与php5.5+集成了opcache)

xcache

eAccelerator

Opcode原理

例如有如下一段代码

echo 'Hello World';

$a = 1 + 1;

echo $a;

?>

php执行这段代码会经过如下4个步骤(准确的说,通过php的语言引擎Zend)

Scanning(Lexing)将php代码转化为语言片段(Tokens)

Parsing,将Tokens转化为简单而有意义的表达式

Complilation,将表达式编译成Opcode

Execution,顺序执行Opcode,每次一条,从而实现php脚本的功能

如下图

Lexing阶段

Lex 就是一个词法分析的依据表。Zend引擎会会对输入的php代码进行词法分析(切确的说是: Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l(Lex文件) ),从而得到一个一个的词,php中提供了一个函数:token_get_all可以将一段php代码解析成tokens

如果用这个函数分析上面的示例代码,结果如下:

Array

(

[0] => Array

(

[0] => 374

[1] => <?php

[2] => 1

)

[1] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[2] => Array

(

[0] => 317

[1] => echo

[2] => 1

)

[3] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[4] => Array

(

[0] => 316

[1] => "Hello World"

[2] => 1

)

[5] => ;

[6] => Array

(

[0] => 310

[1] => $a

[2] => 1

)

[7] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[8] => =

[9] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[10] => Array

(

[0] => 306

[1] => 1

[2] => 1

)

[11] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[12] => +

[13] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[14] => Array

(

[0] => 306

[1] => 1

[2] => 1

)

[15] => ;

[16] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[17] => Array

(

[0] => 317

[1] => echo

[2] => 1

)

[18] => Array

(

[0] => 377

[1] =>

[2] => 1

)

[19] => Array

(

[0] => 310

[1] => $a

[2] => 1

)

[20] => ;

[21] => Array

(

[0] => 376

[1] => ?>

[2] => 1

)

)

分析这个返回结果我们可以发现,源码中的字符串,字符,空格都会原样返回。每个源代码的字符都会出现在相应的顺序处。而其他的例如标签,操作符,语句 都被转化成一个包含;两部分的array:Token ID(也就是在Zend内部的该Token的对应码,比如T_ECHO,T_STRING)和 源码中原来的内容

Parsing阶段

Parsing阶段首先会丢弃Tokens array中的多余空格,然后将剩余的Tokens转换成一个一个简单的表达式

echo a contanst string

add two numbers together

store the result of the prior expression to a variable

echo a variable

Complilation阶段

Complilation阶段会把Tokens编译成一个个op_array,每个op_array包含如下5个部分

Opcode数字的标示,指明了每个op_array的操作类型,比如add,echo

结果  存放Opcode的结果

操作数1 给Opcode的操作数

操作数2

扩展值 1个整形用来区别被重载的操作符

比如我的php代码会被Parsing成:

ZEND_ECHO 'Hello World'

ZEND_ADD   ~0 1 1

ZEND_ASSIGN !0 ~0

ZEND_ECHI ~0

在上面的代码我们并没有看到 $a,去哪里了?

这个就要介绍操作数了,每个操作数都是由以下两个部分组成:

op_type :为IS_CONST,IS_TMP_VAR,IS_VAR,IS_UNUESED or IS_CV

u 一个联合体,根据op_type不同 分别用不同的类型保存这个操作数的值(const)或者左值(var)

而对于var来说,每个var也不一样

IS_TMP_VAR 顾名思义就是这是一个临时变量,保存一些op_array 的结果,以便接下来的op_array 使用,这种的操作数u保存着一个指向变量表的一个句柄(整数),这个操作数一般用~ 开头 ,比如 ~0 表示 变量表中0号的未知的临时变量

IS_VAR 这是我们一般意义上的变量,他们以$开头表示

IS_CV 表示ZE2.1/PHP5.1以后的编译器使用的一种cache机制,这种变量保存着被应用的变量地址,当一个变量第一次被应用的时候 ,就会被CV起来,以后对这个变量的引用就不需要再去查找active符号表了,CV变量已!开头表示

这么开来 我的$a 被优化成了!0了

Opcode Cache原理

通过上面的介绍,我们了解了opcode,关于opcode cache的原理图大致如下

我们可以看到除了 Lexing,Parsing,Complilation,Execution阶段 还多了一个阶段:检测文件是否有更新

如果没有更新直接获取缓存的opcode,直接进入Execution阶段然后返回结果

如果更新了就按照原来流程(加入一个环节:图中红色部分 缓存opcode)

php 查询缓存原理,深入了解php opcode缓存原理相关推荐

  1. 深入理解PHP Opcode缓存原理

    什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译,减少 ...

  2. opcode php 缓存,深入理解PHP Opcode缓存原理

    什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译,减少 ...

  3. PHP-深入理解Opcode缓存

    1.什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译, ...

  4. 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项

    MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能.本 ...

  5. opcode php 5.4,为PHP5.4开启Zend OPCode缓存

    为PHP5.4开启Zend OPCode缓存 编译步骤: 复制代码 代码如下: git clone git://github.com/zend-dev/ZendOptimizerPlus.git cd ...

  6. php 5.4 opcode,PHP Opcode缓存总结

    1.Zend Optimizer v3.x.x v2.x.x 在PHP-5.2.x以前的PHP版本使用,用优化代码的方法来提高PHP应用程序的执行速度,理论上要比不使用ZO要快40%-100%.实现的 ...

  7. opcode加密php代码,总结Opcode缓存和PHP代码的加密

    1.Zend Optimizer v3.x.x v2.x.x 在PHP-5.2.x以前的PHP版本使用,用优化代码的方法来提高PHP应用程序的执行速度,理论上要比不使用ZO要快40%-100%.实现的 ...

  8. php 的opcode缓存apc以及其安装

    先说说php程序的执行流程吧,说明了这个,才好开始我们的优化之旅. 客户端(譬如浏览器) ->请求Get hello.php -->cgi服务器接(譬如apache)收到请求,根据配置寻找 ...

  9. 《如何与面试官处朋友》系列-缓存击穿、穿透、雪崩场景原理大调解

    前面我们提到分布式多级缓存架构的全貌,但总感觉少了些什么东西.在这样大的场景下面,如果遇到缓存使用问题那可咋办?但自古英雄出少年,相信此刻你已踏马西去,正走在寻找答案上得夕阳西下.每每面谈Redis大 ...

最新文章

  1. 使用Xcode和Instruments调试解决iOS内存泄露(转)
  2. All input tensors must be on the same device
  3. Mac安装webpack报错gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1解决
  4. [爬虫-python]爬取京东100页的图书(机器学习)的信息(价格,打折后价格,书名,作者,好评数,差评数,总评数)
  5. 最近围绕生鲜社区团购的一些事
  6. jquery-easyui中datagrid扩展,隐藏显示表头功能
  7. 【Python】python帮助文档
  8. MDT2012配置无人职守安装
  9. java的class文件在哪里_传统上,你在哪里存储Java .class文件?
  10. 【 Ubuntu 】谷歌输入法——繁体简体切换
  11. 使用HAL_IWDG_Refresh()函数,可能造成硬件错误
  12. Ax=b解,向量空间的基、维度(Part IV)
  13. cmd批处理文件格式
  14. [搜索 meet in the middle+哈希] ProjectEuler 598. Split Divisibilities
  15. warframe星际战甲氏族颜料35种全获取机制和获取流程攻略
  16. 从一个置顶CPT广告学习计算广告设计要点
  17. C语言|博客作业04
  18. windows函数(system)
  19. Git ---- 自建代码托管平台-GitLab
  20. 机器学习三剑客之Matplotlab

热门文章

  1. 无闻go编程基础笔记
  2. Linux常用函数(部分收集)
  3. python生成一笔画_python求解微信小游戏——一笔画完
  4. 核密度函数详解,核密度函数图如何看?
  5. 杰理之杰理新一代蓝牙耳机芯片【篇】
  6. MS6212可替换TI PCA9306、SGM4553用于开漏模式和推拉模式的 2bit 双向电平转换器
  7. 【雷达通信】雷达脉冲压缩含Matlab源码
  8. 浅谈Android自定义锁屏页的发车姿势
  9. 单元测试工具之Mockito
  10. android 好的 钢琴软件,真正完美的android钢琴软件