Rumah pembangunan bahagian belakang PHP7 一起看看php7和PHP5对比的新特性和性能优化

一起看看php7和PHP5对比的新特性和性能优化

Feb 04, 2021 am 09:13 AM
php5 php7

一起看看php7和PHP5对比的新特性和性能优化

推荐(免费):PHP7

1、抽象语法树( AST)

   1)在 PHP5中,从 php 脚本到 opcodes 的执行的过程是:

  1. Lexing:词法扫描分析,将源文件转换成 token 流;
  2. Parsing:语法分析,在此阶段生成 op arrays。

2)PHP7 中在语法分析阶段不再直接生成 op arrays,而是先生成 AST,所以过程多了一步:

  1. Lexing:词法扫描分析,将源文件转换成 token 流;
  2. Parsing:语法分析,从 token 流生成抽象语法树;
  3. Compilation:从抽象语法树生成 op arrays。

添加了抽象语法树:内存的使用增加了,但是执行时间上却有所降低

AST在PHP编译过程作为一个中间件的角色,替换原来直接从解释器吐出opcode的方式,让解释器(parser)和编译器(compliler)解耦,可以减少一些Hack代码,同时,让实现更容易理解和可维护

2、Natice TLS

 

PHP在多线程模式下,需要解决“线程安全”(TS,Thread Safe)的问题,因为线程是共享进程的内存空间的,所以每个线程本身需要通过某种方式,构建私有的空间来保存自己的私有数据,避免和其他线程相互污染。

而PHP5采用的方式,就是维护一个全局大数组,为每一个线程分配一份独立的存储空间,线程通过各自拥有的key值来访问这个全局数据组。而这个独有的key值在PHP5中需要传递给每一个需要用到全局变量的函数,PHP7认为这种传递的方式并不友好,并且存在一些问题。因而,尝试采用一个全局的线程特定变量来保存这个key值。

3、指定参数 返回值类型

PHP语言一个非常重要的特点就是“弱类型”,它让PHP的程序变得非常容易编写.

PHP7可选的方式支持类型定义,除此之外,还引入了一个开关指令declare(strict_type=1);,当这个指令一旦开启,将会强制当前文件下的程序遵循严格的函数传参类型和返回类型。

4、zval 结构的变化

在PHP5的时候, zval的定义如下:

struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
  zend_ast *ast;
  } value;
zend_uint refcount__gc;
zend_uchar type;
  zend_uchar is_ref__gc;
};
Salin selepas log masuk

首先这个结构体的大小是(在64位系统)24个字节, 我们仔细看这个zval.value联合体, 其中zend_object_value是最大的长板, 它导致整个value需要16个字节, 这个应该是很容易可以优化掉的, 比如把它挪出来, 用个指针代替,因为毕竟IS_OBJECT也不是最最常用的类型.

第二, 这个结构体的每一个字段都有明确的含义定义, 没有预留任何的自定义字段, 导致在PHP5时代做很多的优化的时候, 需要存储一些和zval相关的信息的时候, 不得不采用其他结构体映射, 或者外部包装后打补丁的方式来扩充zval, 比如5.3的时候新引入专门解决循环引用的GC, 它不得采用如下的比较hack的做法

第三, PHP的zval大部分都是按值传递, 写时拷贝的值, 但是有俩个例外, 就是对象和资源, 他们永远都是按引用传递, 这样就造成一个问题, 对象和资源在除了zval中的引用计数以外, 还需要一个全局的引用计数, 这样才能保证内存可以回收. 所以在PHP5的时代, 以对象为例, 它有俩套引用计数, 一个是zval中的, 另外一个是obj自身的计数:

第四, 我们知道PHP中, 大量的计算都是面向字符串的, 然而因为引用计数是作用在zval的, 那么就会导致如果要拷贝一个字符串类型的zval, 我们别无他法只能复制这个字符串. 当我们把一个zval的字符串作为key添加到一个数组里的时候, 我们别无他法只能复制这个字符串. 虽然在PHP5.4的时候, 我们引入了INTERNED STRING, 但是还是不能根本解决这个问题.

还比如, PHP中大量的结构体都是基于Hashtable实现的, 增删改查Hashtable的操作占据了大量的CPU时间, 而字符串要查找首先要求它的Hash值, 理论上我们完全可以把一个字符串的Hash值计算好以后, 就存下来, 避免再次计算等等

第五, 这个是关于引用的, PHP5的时代, 我们采用写时分离, 但是结合到引用这里就有了一个经典的性能问题:

第六, 也是最重要的一个, 为什么说它重要呢? 因为这点促成了很大的性能提升, 我们习惯了在PHP5的时代调用MAKE_STD_ZVAL在堆内存上分配一个zval, 然后对他进行操作, 最后呢通过RETURN_ZVAL把这个zval的值”copy”给return_value, 然后又销毁了这个zval, 比如pathinfo这个函数:

5、异常处理

PHP 5 的 try ... catch ... finally 无法处理传统错误,如果需要,你通常会考虑用 set_error_handler() 来 Hack 一下。但是仍有很多错误类型是 set_error_handler() 捕捉不到的

PHP 7引入 Throwable 接口,错误及异常都实现了 Throwable,无法直接实现 Throwable,但可以扩展 \Exception 和 \Error 类。可以用 Throwable 捕捉异常跟错误。\Exception 是所有PHP及用户异常的基类;\Error 是所有内部PHP错误的基类。

$name = "Tony";
try {
    $name = $name->method();
} catch (\Error $e) {
    echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
 
try {
    $name = $name->method();
} catch (\Throwable $e) {
    echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
 
try {
    intp(5, 0);
} catch (\pisionByZeroError $e) {
    echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
Salin selepas log masuk

6、hashtable 的变化

7、执行器

8、新的参数解析方式

PHP5  对应的参数解析 zend_parse_parament,

PHP7对应的参数解析:fast_zpp  

Atas ialah kandungan terperinci 一起看看php7和PHP5对比的新特性和性能优化. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Akan R.E.P.O. Ada Crossplay?
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Apakah perbezaan antara php5 dan php8 Apakah perbezaan antara php5 dan php8 Sep 25, 2023 pm 01:34 PM

Perbezaan antara php5 dan php8 adalah dari segi prestasi, struktur bahasa, sistem jenis, pengendalian ralat, pengaturcaraan tak segerak, fungsi perpustakaan standard dan keselamatan. Pengenalan terperinci: 1. Peningkatan prestasi Berbanding dengan PHP5, PHP8 mempunyai peningkatan besar dalam prestasi PHP8 memperkenalkan pengkompil JIT, yang boleh menyusun dan mengoptimumkan beberapa kod pelaksanaan frekuensi tinggi, dengan itu meningkatkan kelajuan berjalan; PHP8 memperkenalkan beberapa struktur dan fungsi bahasa baharu PHP8 menyokong parameter yang dinamakan, membenarkan pembangun menghantar nama parameter dan bukannya susunan parameter, dsb.

Bagaimana untuk memasang sambungan mongo dalam php7.0 Bagaimana untuk memasang sambungan mongo dalam php7.0 Nov 21, 2022 am 10:25 AM

Cara memasang sambungan mongo dalam php7.0: 1. Buat kumpulan pengguna dan pengguna mongodb 2. Muat turun pakej kod sumber mongodb dan letakkan pakej kod sumber dalam direktori "/usr/local/src/" 3. Masukkan direktori "src/" 4. Buka zip pakej kod sumber 5. Buat direktori fail mongodb 6. Salin fail ke direktori "mongodb/" 7. Buat fail konfigurasi mongodb;

Bagaimana untuk menyelesaikan masalah apabila php7 mengesan bahawa port tcp tidak berfungsi Bagaimana untuk menyelesaikan masalah apabila php7 mengesan bahawa port tcp tidak berfungsi Mar 22, 2023 am 09:30 AM

Dalam php5, kita boleh menggunakan fungsi fsockopen() untuk mengesan port TCP. Fungsi ini boleh digunakan untuk membuka sambungan rangkaian dan melakukan beberapa komunikasi rangkaian. Tetapi dalam php7, fungsi fsockopen() mungkin menghadapi beberapa masalah, seperti tidak dapat membuka port, tidak dapat menyambung ke pelayan, dsb. Untuk menyelesaikan masalah ini, kita boleh menggunakan fungsi socket_create() dan fungsi socket_connect() untuk mengesan port TCP.

Apakah yang perlu saya lakukan jika pemalam dipasang dalam php7.0 tetapi ia masih menunjukkan bahawa ia tidak dipasang? Apakah yang perlu saya lakukan jika pemalam dipasang dalam php7.0 tetapi ia masih menunjukkan bahawa ia tidak dipasang? Apr 02, 2024 pm 07:39 PM

Untuk menyelesaikan pemalam yang tidak menunjukkan isu yang dipasang dalam PHP 7.0: Semak konfigurasi pemalam dan dayakan pemalam. Mulakan semula PHP untuk menggunakan perubahan konfigurasi. Semak kebenaran fail pemalam untuk memastikan ia betul. Pasang kebergantungan yang hilang untuk memastikan pemalam berfungsi dengan betul. Jika semua langkah lain gagal, bina semula PHP. Punca lain yang mungkin termasuk versi pemalam yang tidak serasi, memuatkan versi yang salah atau isu konfigurasi PHP.

Bagaimana untuk menukar port 80 dalam php5 Bagaimana untuk menukar port 80 dalam php5 Jul 24, 2023 pm 04:57 PM

Cara menukar port 80 dalam php5: 1. Edit nombor port dalam fail konfigurasi pelayan Apache; mula berjalan pada port baru berjalan pada port.

Apr 09, 2024 pm 01:33 PM

Penyelesaian biasa untuk persekitaran pelayan PHP termasuk memastikan versi PHP yang betul dipasang dan fail yang berkaitan telah disalin ke direktori modul. Lumpuhkan SELinux buat sementara waktu atau selama-lamanya. Semak dan konfigurasikan PHP.ini untuk memastikan sambungan yang diperlukan telah ditambah dan disediakan dengan betul. Mulakan atau mulakan semula perkhidmatan PHP-FPM. Semak tetapan DNS untuk isu penyelesaian.

Cara memasang dan menggunakan php7.0 Cara memasang dan menggunakan php7.0 Nov 30, 2022 am 09:56 AM

Cara memasang dan menggunakan php7.0: 1. Pergi ke laman web rasmi PHP untuk memuat turun versi pemasangan yang sepadan dengan sistem tempatan 2. Ekstrak fail zip yang dimuat turun ke direktori yang ditentukan 3. Buka tetingkap baris arahan dan pergi ke direktori "E:\php7" Hanya jalankan arahan "php -v".

Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Mar 31, 2025 pm 11:54 PM

Bagaimana untuk menetapkan keizinan UnixSocket secara automatik selepas sistem dimulakan semula. Setiap kali sistem dimulakan semula, kita perlu melaksanakan perintah berikut untuk mengubahsuai keizinan UnixSocket: sudo ...

See all articles