0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PHP7在内存方面你是否知道都进行了哪些优化

冬至配饺子 来源:开发内功修炼 作者:张彦飞allen 2022-08-30 17:08 次阅读

前面我们讨论了内存的工作原理,也进行了一些性能相关的测试。那么今天开始我们来看几个在实践中的应用。首先我们先从PHP开始。2015年,PHP7的发布可以说是在技术圈里引起了不小的轰动,因为它的执行效率比PHP5直接翻了一倍。PHP7在内存方面,你是否知道作者都进行了哪些优化?几个核心结构体的改进只是表面上看起来优化的几个字节那么简单?让我们从几个核心的数据结构改进开始看起。

1 PHP7zval的变化

1、php5.3中的zval:

pYYBAGMN0taADI7ZAACph_e53O8634.png

我们这里只讨论64位操作系统下的情况。该zval_struct结构体中的由四个成员构成,其中zvalue_value稍微复杂一些,是一个联合体。联合体中最长的成员是一个指针加一个int,8+4=12字节。但是默认情况下,会进行内存对齐,故zval_struct会占用16字节。那么。

_zval_struct总的字节 = value(16)+ refcount__gc(4)+ type(1)+ is_ref__gc(1)= 占用22字节。

最后再考虑下内存对齐,实际占用24字节。(如果算的有点晕话,感兴趣的同学可以写段简单的测试代码,使用sizeof查看一下)

2、PHP7.2中的zval

poYBAGMN0uyAUol1AADs2EZskZs450.png

7.2中的zval_struct结构体里由3个成员构成,其中zend_value看起来比较复杂,实际上只是一个8字节的联合体。u1也是一个联合体,占用是4个字节。u2也一样。这样zval_struct就实际占用16个字节。

2 PHP7 HashTable的变化

1、PHP5.3里的HashTable:

pYYBAGMN0v-AGU2NAACNlGKBu8M639.png

在5.3里HashTable就是一个大struct, 有点小复杂,我们拆开了细说,

uint nTableSize 4字节

uint nTableMask 4字节

uint nNumOfElements 4字节,

ulong nNextFreeElement 8字节 注意这前面的4个字节会被浪费掉,因为nNextFreeElement的开始地址需要对齐

Bucket *pInternalPointer 8字节

Bucket *pListHead 8字节

Bucket *pListTail 8字节

Bucket **arBuckets 8字节

dtor_func_t pDestructor 8字节

zend_bool persistent 1字节

unsigned char nApplyCoun 1字节

zend_bool bApplyProtection 1字节

最终,总字节数 = 4+4+4+4(nNextFreeElement前面这四个字节会留空)+8+8+8+8+8+8+1+1+1 = 67字节。再加上结构体本身要对齐到8的整数倍,所以实际占用72字节。

2、PHP7.2里的HashTable:

pYYBAGMN0xKAQDrkAACWEr2NQKE768.png

在7.2里HashTable

zend_refcounted_h gc 看起来唬人,实际就是个long,占用8字节

union... u 占用4字节

uint32_t 占用4字节

Bucket* 指针占用8字节

uint32_t nNumUsed 占用4字节

uint32_t nNumOfElements 占用4字节

uint32_t nTableSize 占用4字节

uint32_t nInternalPointer 占用4字节

zend_long nNextFreeElement 占用8字节

dtor_func_t pDestructor 占用8字节

总占用

字节数 = 8+4+4+8+4+4+4+4+8+8 = 56字节,并且正好达到了内存对齐的状态,没有额外的浪费。

另外还有PHP源代码里经常出镜的Buckets也从72下降到了32字节,这里我就不翻源代码了。

3 优化思想精髓

当当当,敲黑板,重点来了!我们看了两个核心数据结构的结构体变化,这上面的优化都是什么含义呢?拿HashTable举例,貌似从72字节优化到了56字节,这内存节约的也不是特别多嘛,才20%多而已!但这中间其实隐藏了两个较深层次优化思路:

第一、你是否记得我们前面CPU在向内存要数据的时候是以Cache Line为单位进行的,而我们说过Cache Line的大小就是64字节。回过头来看HashTable,在7.2里的56字节,只需要CPU向内存进行一次Cache Line大小的burst IO,就够了。而在5.3里的72字节,虽然只比Cache Line大了那么一丢丢,但是对不起,必须得进行两次burst IO才可以。所以,在计算机里,56字节相对72字节实际上是翻倍的性能提升!!

第二、CPU的L1、L2、L3的容量是固定的几十K或者几十M。假设Cache的都是HashTable,那么Cache容量不变的条件下,能Cache住的HashTable将会翻倍,缓存命中率提升一大截。要知道L1命中后只需要1ns多一点的耗时,而如果穿透到内存的话可能就需要40多纳秒的延时了,整整差了几十倍。

所以PHP内核的作者大牛深谙CPU与内存的工作原理,表面上看起来只是几个字节的节约,但是实际上爆发出了巨大的性能提升!!



审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10409

    浏览量

    206463
  • 内存
    +关注

    关注

    8

    文章

    2759

    浏览量

    72682
  • 操作系统
    +关注

    关注

    37

    文章

    6259

    浏览量

    121836
  • PHP
    PHP
    +关注

    关注

    0

    文章

    451

    浏览量

    26445
收藏 人收藏

    评论

    相关推荐

    什么是HBM3E内存?Rambus HBM3E/3内存控制器内核

    Rambus HBM3E/3 内存控制器内核针对高带宽和低延迟进行了优化,以紧凑的外形和高能效的封装为人工智能训练提供了最大的性能和灵活性。
    发表于 03-20 14:12 431次阅读
    什么是HBM3E<b class='flag-5'>内存</b>?Rambus HBM3E/3<b class='flag-5'>内存</b>控制器内核

    使用STM32H7的AD进行了7M频率的采集信号,采集进去后可以实现实时处理吗?

    使用STM32H7的AD进行了7M频率的采集信号,采集进去后可以实现实时处理吗?
    发表于 03-08 08:10

    数组和链表在内存中的区别 数组和链表的优缺点

    数组和链表在内存中的区别 数组和链表的优缺点  数组和链表是常见的数据结构,用于组织和存储数据。它们在内存中的存储方式以及优缺点方面存在一些显著的差异。本文将详细探讨这些差异以及它们的优缺点。 1.
    的头像 发表于 02-21 11:30 242次阅读

    软件测试的7大原则,漏了几条?

    of error-fallacy) 99%无错误的软件仍然可能无法使用,如果针对缺陷要求对系统进行了全面测试,则可能是这种情况。软件测试不仅仅是为了发现缺陷,而且还要检查软件是否满足业务需求。没有错误是谬论,即如
    发表于 01-18 09:39

    知道无人机性能是否优异,看这3个参数

    拿纵横最新发布的CW-007大鹏来说。飞机的外形拥有完全的自主知识产权。在外形设计方面使用了CFD数值优化技术,对机翼的翼型分布和翼尖的上翘延伸小翼进行了优化,最大限度地提高升阻比,保
    的头像 发表于 12-10 11:56 682次阅读
    想<b class='flag-5'>知道</b>无人机性能<b class='flag-5'>是否</b>优异,看这3个参数

    php的mysql无法启动

    ,以便帮助读者快速解决相关问题。 一、安装环境配置检查 1.1 PHP版本检查 在使用PHP连接MySQL之前,首先要确保PHP版本的兼容性。查看所使用的PHP版本
    的头像 发表于 12-04 15:59 543次阅读

    php运行环境本地测试地址是

    PHP运行环境本地测试地址是指在本地计算机上搭建的用于测试和运行PHP代码的的环境地址。搭建该运行环境可以方便开发人员在本地进行开发、调试和测试工作,以提高开发效率和优化代码质量。本文
    的头像 发表于 12-04 15:25 283次阅读

    MMU如何知道页表在内存中的具体地址

    MMU怎么知道这个页表在内存中的具体地址呢? 通常CPU会提供一个页表基址寄存器给操作系统使用,用于给MMU指示页表的基地址。不同处理器架构对应的寄存器也不一样: x86:CR3(Control
    的头像 发表于 10-08 11:52 577次阅读
    MMU如何<b class='flag-5'>知道</b>页表<b class='flag-5'>在内存</b>中的具体地址

    JVM内存大对象监控和优化问题描述及解决办法

    服务器内存问题是影响应用程序性能和稳定性的重要因素之一,需要及时排查和优化。本文介绍了某核心服务内存问题排查与解决过程。首先在JVM与大对象优化
    的头像 发表于 08-28 11:39 599次阅读
    JVM<b class='flag-5'>内存</b>大对象监控和<b class='flag-5'>优化</b>问题描述及解决办法

    STM32单片机的内存优化策略

    在单片机开发中,内存优化是至关重要的,它不仅能够降低成本,还可以提高性能。本文将深入讨论如何在STM32单片机和C语言的环境中实施内存优化策略,以确保项目的顺利
    发表于 08-21 09:21 1170次阅读
    STM32单片机的<b class='flag-5'>内存</b><b class='flag-5'>优化</b>策略

    ARM7TDMI (Rev 3)核心处理器产品概述

    针对成本和功率敏感的应用程序进行了优化,提供了便携式嵌入式应用程序所需的低功耗、小尺寸和高性能。 ARM7TDMI-s内核是ARM7TDMI内核的可合成版本,有verilog和vhdl
    发表于 08-02 10:25

    2个esp8266并用deauther对它们进行了闪烁以进行渗透测试,连接到网页192.168.4.1是否会同时连接到它们?

    大家好,最近这个问题一直困扰着我。我现在有 5 个 esp8266,我想知道, 如果我拿了其中的 2 个 esp8266 并用 deauther 对它们进行了闪烁以进行渗透测试,那么连接到网页
    发表于 06-01 10:13

    求助,如何检查是否使用“NXP 的在线 NFC 天线设计工具”正确地进行了定制天线设计?

    我们计划在我们的几个标签产品中使用 NTA5332,我们想检查我们是否使用“NXP 的在线 NFC 天线设计工具”正确地进行了定制天线设计。 之前我们做了一些抄袭dev的设计。使用无源负载调制
    发表于 06-01 06:17

    S32K144定制评估板无法启动是怎么回事?

    原理图是否正确吗?我参考了该微控制器的所有可用文档,并与 NXP 官方 S32K144 评估板的原理图进行了交叉检查。一切似乎都在检查。
    发表于 05-30 06:35

    带有Web管理的Nodemcu的OTA更新

    使用进行了优化,以便为您的脚本分配最大可用内存。 我已经部署了很多 ESP,由于我的家庭自动化系统的修改,我需要定期更新它们。在这种情况下,有必要通过 USB 连接它们并上传新脚本。现在,我可以使用一种通用管理方式远程管理我所有
    发表于 05-04 07:30