首页 > 编程知识 正文

static变量在类加载时被初始化,数据结构C++

时间:2023-05-04 03:31:00 阅读:14784 作者:3908

这篇文章大部分引用了AST的RFC文档。

我的官方小组点击这里。

本文不告诉你抽象语法树是什么。 这需要自己理解。 这里介绍了AST给PHP带来的一些变化。

新的执行过程

PHP7内核有一个重要的变化,就是内置了AST。 在php5中,从PHP脚本到opcodes的执行过程如下:

1、Lexing :词法扫描分析,将源文件转换为token流;

2、Parsing :语法分析,在此阶段生成op arrays。

3、由于PHP7在语法分析阶段不是直接生成op arrays,而是AST,所以流程进一步增加:

4、Lexing )词法扫描分析,将源文件转换为token流;

5、Parsing :语法分析,token流生成抽象语法树;

6、Compilation :由抽象语法树生成op arrays。

运行时间和内存消耗

根据以上步骤,这比上一个进程多了一步,所以从常识上来说,程序的运行时间和内存使用量会增加。 然而,实际上内存使用量在增加,但执行时间却在下降。

以下结果分别使用小(代码约100行)、中(约700行)、大(约2800行)三个脚本进行了测试,对脚本进行了测试。

每个文件编译100次的运行时间(注意文章测试时间为14年,PHP7有时也称为PHP-NG ) :

每个文件编译100次的运行时间(注意文章测试时间为14年,PHP7有时也称为PHP-NG ) :

单编译时的内存峰值:

一次编译的测试结果可能不代表实际使用情况。 使用PhpParser进行完全项目测试的结果如下所示。

测试表明,使用AST后程序的运行时间总体上提高了约10%到15%,但内存消耗也有所增加,在大文件的单次编译中明显增加,但在项目运行中并没有那么严重。

请注意,以上所有结果都是没有Opcache的情况,并且在生产环境中打开Opcache时,内存消耗增加也不是什么大问题。

意义的变化

光靠时间上的优化似乎不是使用AST的充分理由。 其实实现AST不是为了时间优化上的考虑,而是为了解决语法上的问题。 看看意义上的变化吧。

yield不需要括号

在PHP5实现中,如果在表达式上下文(例如赋值表达式的右侧)中使用yield,则必须在智能冰淇淋的两侧使用括号。

$result=yield fn (; //不合法

$result=(yieldfn ) ); //合法的

这只是PHP5实现方式的限制,在PHP7中不再需要括号。 所以以下写法也是合法的:

$result=yield;

$result=yield $v;

$result=yield $k=$v;

当然,必须遵循颐指气使的应用场景。

括号不影响动作

在PHP5中,$foo['bar']='baz '和$foo['bar']='baz '两个语句的含义不同。 前者的写法不合法。 可以得到以下错误。

($foo ) ) ) bar )=) baz );

# PHP Parse error: Syntax error,unexpected ' [ '在线1

但是,在PHP7中,两种写法表示相同的意思。

同样,如果函数的参数括在括号中,则类型检查有问题。 PHP7也解决了这个问题。

函数函数

返回[ ];

}

function ByRef (阵列$ a ) {

}

byref () ) func ) );

除非在byref(func ) )中调用上述代码,否则PHP5不会发出警告。 但是,在PHP7中,无论func ) )两侧是否有括号,都会出现以下错误:

phpstrictstandards 3360 onlyvariablesshouldbepassedbyreference .

list ()变化

list关键词的行为发生了很大的变化。 list为变量赋值的顺序(等号左右同时的顺序)以前是从右到左,现在是从左到右:

list($array[]、$array[]、$ array [ ]=[ 1,2,3 ];

var_dump($array;

//PHP 5: $ array=[ 3,2,1 ]

//PHP7: $a

rray = [1, 2, 3]

# 注意这里的左右的顺序指的是等号左右同时的顺序,

# list($a, $b) = [1, 2] 这种使用中 $a == 1, $b == 2 是没有疑问的。

产生上面变化的原因正是因为在 PHP5 的赋值过程中,3 会最先被填入数组,1 最后,但是现在顺序改变了。

同样的变化还有:

$a = [1, 2];

list($a, $b) = $a;

// PHP5: $a = 1, $b = 2

// PHP7: $a = 1, $b = null + "Undefined index 1"

这是因为在以前的赋值过程中 $b 先得到 2,然后 $a 的值才变成 1,但是现在 $a 先变成了 1,不再是数组,所以 $b 就成了 null。

list 现在只会访问每个偏移量一次:

list(list($a, $b)) = $array;

// PHP5:

$b = $array[0][1];

$a = $array[0][0];

// PHP7:

// 会产生一个中间变量,得到 $array[0] 的值

$_tmp = $array[0];

$a = $_tmp[0];

$b = $_tmp[1];

空的 list 成员现在是全部禁止的,以前只是在某些情况下:

list() = $a; // 不合法

list($b, list()) = $a; // 不合法

foreach ($a as list()) // 不合法 (PHP5 中也不合法)

引用赋值的顺序

引用赋值的顺序在 PHP5 中是从右到左的,现在时从左到右:

$obj = new stdClass;

$obj->a = &$obj->b;

$obj->b = 1;

var_dump($obj);

// PHP5:

object(stdClass)#1 (2) {

["b"] => &int(1)

["a"] => &int(1)

}

// PHP7:

object(stdClass)#1 (2) {

["a"] => &int(1)

["b"] => &int(1)

}

__clone 方法可以直接调用

现在可以直接使用 $obj->__clone() 的写法去调用 __clone 方法。__clone 是之前唯一一个被禁止直接调用的魔术方法,之前你会得到一个这样的错误:

Fatal error: Cannot call __clone() method on objects - use 'clone $obj' instead in ...

变量语法一致性

在新的实现上,以前的一些语法表达的含义和现在有些不同,具体的可以参照下面的表格:

整体上还是以前的顺序是从右到左,现在从左到右,同时也遵循括号不影响行为的原则。这些复杂的变量写法是在实际开发中需要注意的。

更多学习内容请访问:八重樱:腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)​zhuanlan.zhihu.com

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。