php 引用变量-已经存在了 20 多年的 PHP 仍然是最好的编程语言吗?

2023-08-26 0 6,197 百度已收录

点击上方“CSDN”,选择“置顶公众号”

关键时刻,第一时间发货!

作者简介:Panda,一名热爱技术、喜欢刨根问底、爱分享、热爱开源、活跃于开源社区、乐于分享和交流的程序员。 PHP开源项目贡献者,对网络安全、PHP内核、Nginx内核、MySQL有一定的研究。

本文来自作者在GitChat上的主题为“2017年PHP社区总结,2018年PHP发展展望”的分享。

1、2017PHP社区总结:回顾PHP语言本身的升级与变化

我们先回顾一下PHP的发展历史:

作为Web开发领域性价比最高的语言,PHP已经存在了20多年。

注:一个网站可以使用多种语言作为其开发语言。 本文包含大量鸟哥PPT的截图。 图片版权归鸟哥所有。

PHP 始于 1994 年,最初是由 Rasmus Lerdorf 的一个简单想法形成的。 当时,Rasmus用C语言编写了一个应用程序,用于跟踪和维护自己的个人主页。

但 Rasmus 对其进行了扩展,使其可以应用于 Web 表单并与数据库交互。 就这样,PHP的第一个版本诞生了。 Rasmus 将其称为“PersonalHomePage/FormsInterpreter”或简称 PHP/FI。

用Rasmus自己的话说:本来他并不想开发一种新的编程语言,随着PHP/FI的发展,它逐渐不再受他的控制。 就这样一个开发团队离开了,但在 1997 年 11 月,第二个版本 PHP/FI2 发布了。

展望未来,ZeevSuraski和AndiGutmans的出现将PHP的发展推向了一个新的里程碑。

1997年,两人重写了PHP类库,产生了PHP的第三个版本,PHP3,也就是这个时候,名称从PHP/FI改为PHP(Hypertext Preprocessor超文本预处理器)。

时隔一年,两人在1998年重新编写了PHP的核心代码。过了近一年,1999年Zend引擎诞生。随后在2000年5月,搭载第一代zend引擎的PHP4即将发布。

此后,其发展进入缓慢阶段。 搭载第一代Zend引擎的PHP4在2008年8月达到4.4.9后,就一直没有后续开发,也没有安全更新。

我最早使用的PHP4程序应该是DEDECMS。 此时,PHP仍然是一种面向过程的编程方法。

2004年6月,PHP的发展达到了第二个里程碑。 带有 ZendEngineII 的 PHP5 即将发布。 在这个PHP5中,开始了面向对象的支持,但是性能明显提升。

直到2008年,很多程序不再支持PHP4版本,而换成了PHP5。

然后,是时候下一个角色登场了,他的出现将PHP从5提升到了PHP6。 他的名字叫安德烈·兹米耶夫斯基。

当时PHP5发布后,PHP收到了各种反馈,反馈的内容就是PHP中缺乏对编码转换的支持。 于是在2005年,ICU库被Andrei领导的PHP嵌入。 并使文本字符串以 unicode-16 呈现。

此举对PHP本身以及用户的编码方式形成了很大的改变,于是PHP6应运而生。

虽然变化很大,但由于开发人员对变化的理解不够充分,转换为 unicode-16 编码(在 Web 环境中很少使用)会带来性能的提升。 种种诱因导致这个项目陷入停滞。

而2009年发布的PHP5.3和2010年发布的5.4几乎包含了PHP6移植的所有功能。 于是2010年该项目被叫停,直到2014年才被接受。

2014-2015年期间,PHP7即将发布。 起初,对于这个版本的PHP7存在一些争议。 由于最初的 PHP6 还没有发布,就夭折了,所以直接转到版本 7 并不是很合适。

然而,PHP6这个名字已经在一些学术论文和书籍中被引用,所以人们最终将其定位为7。

PHP7 的主要目标是通过构建 Zend 引擎来优化 PHP 的性能,同时保留语言兼容性。 因为是其引擎的构建,PHP7的引擎目前是第三代ZendEngine3。

明天PHP7即将发布。 纵观它从诞生到发展,有成功也有失败,明天的成功只是从今天的简单来看开始的。

作为一名程序员,如果我现在的一个想法能够在多年之后取得如此伟大的成就,一个“骄傲”如何能够表达出来。 类似的情况也发生在另一个人身上,他就是linux的创始人linus。

不管怎样,作为一名PHP程序员,我自然很高兴明天能看到PHP的成果,并且我会在PHP的道路上继续走下去,希望PHP的发展越来越好。

1、PHP7.0的优化

PHP中的各类变量,虽然真正的存储载体是Zval,其特点是具有包容性和包容性。 本质上,它是C语言实现的一个结构体(struct)。

对于写PHP的朋友来说,可以简单理解为类似于数组链表的东西。

PHP5的zval,显存抢占24字节:

PHP7的zval,内存抢占16字节:

Zval从24字节增加到16字节,为什么增加呢?

这里需要补充一点C语言基础,以帮助不熟悉C的朋友理解。 结构和联合(组合)有点不同。 Struct的每个成员变量必须占用独立的显存空间,而union中的成员变量共享显存空间。

也就是说,如果其中一个成员变量发生改变,那么公共空间就会改变,其他成员变量的记录就会消失。 为此,尽管成员变量看起来多了很多,但实际占用的显存空间却增加了。

此外,特性也发生了显着变化,一些简单类型不再使用引用。

Zval 结照明:

图中的Zval是由两个64bit组成(1字节=8bit,bit就是“位”)。 如果变量类型是long或者bealoon,宽度不超过64bit,就会直接存入value中,下面就不会再引用了。

当变量类型为数组、objec、字符串等超过64bit时,存储的值是一个指向真实存储结构地址的针。

对于简单变量类型,Zval存储非常简单高效。

不需要引用的类型:NULL、Boolean、Long、Double; 需要引用的类型:String、Array、Object、Resource、Reference。

(1)内部类型zend_string

Zend_string是一个实际存储字符串的结构体,实际内容会存储在val(char,字符类型)中,val是一个宽度为1的char字段,方便成员变量占用)。

该结构的最后一个成员变量使用 char 字段而不是 char*。 这里有一个小优化方法,可以减少CPU的cachemiss。

如果使用char字段,则malloc申请上述结构体的内存时,是在同一个区域申请的,一般宽度为sizeof(_zend_string)+实际的char存储空间。

但如果使用char*,则该位置仅存储一个指针,真正存储在另一个独立的显存区域。

使用char[1]和char*分配视频内存的比较:

从逻辑实现上看,两者显然没有太大区别,疗效也很相似。

事实上,当这块显存加载到CPU中时,就变得很不一样了。 由于后者是连续分配在一起的同一块显存,所以CPU读取时一般可以一起获取(因为会在同一级缓存中)。

对于前者,由于有两块显存数据,当CPU读取第一块显存时,很可能第二块显存的数据不在同级缓存中,从而导致CPU要到L2(二级缓存)以下查找,甚至到显存区域去寻找想要的第二显存数据。

两者都会导致CPUCacheMiss,并且两者的持续时间最多可以相差100倍。

另外,在复制字符串时,使用引用参数,zend_string可以防止显存复制。

(2) PHP链表的变化(HashTable和ZendArray)

在编译PHP程序的过程中,最常用的类型就是链表。 PHP5的链表是通过HashTable实现的。

如果使用一种比较简单的泛化方法,可以将其视为一种支持单向数组的HashTable。 除了支持通过形参的key进行哈希映射访问元素外,还可以通过foreach以访问单向数组的形式来遍历链表元素。

这张图看起来很复杂,各种指针到处跳转,当我们通过键值访问某个元素的内容时,有时需要3次指针跳转才能找到需要的内容。

最重要的一点是,这个链表的元素存储在不同的显存区域中。

同理,当CPU读取时,由于它们很可能不在同一级缓存中php 引用变量,因此CPU将不得不搜索较低级缓存甚至显存区域,这意味着CPU缓存命中会增加,从而减少更多的持续时间。

PHP7的ZendArray:

新版本的链表结构非常简单、引人注目。 最大的特点是整个链表和哈希映射表的元素都连接在一起,并分配在同一块显存中。

如果是遍历一个简单的整型字段,效率会特别快,因为链表元素(Bucket)本身是在同一个显存中连续分配的,但是链表元素的zval里面会存储整型元素,并且不再有指针的外部链接,所有数据都存储在当前显存区域中。

其实最重要的是,它还可以防止CPUCacheMiss(增加CPU缓存命中率)。

ZendArray 的变化:

(3)函数调用机制(FunctionCallingConvention)

PHP7改进了函数的调用机制。 通过优化参数传递的环节,减少了部分指令,提高了执行效率。

PHP5的函数​​调用机制:

图中,vm栈中的指令send_val与recv参数的指令是相同的,PHP7通过减少这两次重复php 引用变量,实现了函数调用机制的底层优化。

PHP7的函数调用机制:

通过宏定义和内联函数(inline),让编译器提前完成部分工作。 C语言的宏定义会在预处理阶段(编译阶段)执行,提前完成部分工作,程序运行时不需要分配显存。 。

可以实现类似函数的功能,但是没有函数调用压栈、出栈的成本,效率会比较高。

内联函数也是如此。 在预处理阶段,将程序中的函数替换为函数体,实际运行的程序在这里执行,不会有函数调用开销。

PHP7在这方面做了很多优化,将很多需要在运行时阶段进行的工作放到了编译阶段。 比如参数类型的确定(ParametersParsing),因为涉及到固定字符常量。

为此,可以在编译阶段完成,从而提高后续的执行效率。 例如,右图中参数类型的处理方法从右侧的写法优化为左侧宏的写法。

2、PHP7.1的优化

3. PHP7.2的变化

围绕 PHP 的优秀开源项目

1. 框架

2. 组件

3. 工具

4. 项目

PHP在Web生态中的变化

一句话概括了PHP在Web生态中的变化:更快、更高、更强。

国外PHP社区

2. 2018年PHP发展展望

围绕PHP的生态增强

编程语言最重要的生态是,社区活跃则语言兴盛,社区衰落则语言衰落,就像水与鱼的关系一样。

正在开发的libpkd => 扩展原生语言能力,建立运行时标准库。 目前基于Swoole生态已经涌现出很多优秀的框架。

PHP程序员的努力

随着开源的流行,越来越多的PHPers正在贡献自己的力量。 GitHub 上的 PHP 开源项目越来越多,比如 Packagist 上的组件也越来越丰富,PHP 语言本身的性能也在不断提高。 让PHP语言换来新的活力。

参考

免责声明:封面图片由视觉中国付费下载。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php 引用变量-已经存在了 20 多年的 PHP 仍然是最好的编程语言吗? https://www.wkzy.net/game/155007.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务