ホームページ  >  記事  >  バックエンド開発  >  php7 と PHP5 の新機能とパフォーマンスの最適化を見てみましょう。

php7 と PHP5 の新機能とパフォーマンスの最適化を見てみましょう。

coldplay.xixi
coldplay.xixi転載
2021-02-04 09:13:072542ブラウズ

php7 と PHP5 の新機能とパフォーマンスの最適化を見てみましょう。

推奨 (無料): PHP7

1. 抽象構文ツリー(AST)

1) PHP5 では、php スクリプトからオペコードまでの実行プロセスは次のとおりです。

  1. 字句解析:字句スキャン分析、ソース ファイルをトークン ストリームに変換、
  2. #解析: 構文分析、この段階で op 配列を生成します。

2) PHP7 では、op 配列は構文分析フェーズ中に直接生成されなくなりましたが、AST

  1. 字句解析: 字句スキャン分析、ソース ファイルをトークン ストリームに変換する;
  2. 解析: 構文分析、トークン ストリームから抽象構文ツリーを生成;
  3. コンパイル: 抽象構文ツリーから op 配列を生成します。

#抽象構文ツリーを追加: メモリ使用量は増加しましたが、実行時間は減少しました

AST は、PHP のコンパイル プロセスでミドルウェアの役割を果たし、インタープリターからオペコードを直接吐き出す元の方法を置き換え、インタープリター (パーサー) とコンパイラー (コンパイラー) を分離します。と同時に、実装の理解と保守が容易になります。

2. Natice TLS

#PHP は、マルチスレッド モードでの「スレッド セーフティ」(TS、スレッド セーフ) の問題を解決する必要があります。スレッドはプロセスのメモリ空間を共有するため、各スレッド自体を何らかの方法で構築する必要があります。プライベート スペース他のスレッドとの相互汚染を避けるために自分のプライベートデータを保存します。

PHP5 で採用されている方法は、グローバルな大きな配列を維持し、独立した記憶領域を各スレッドに割り当てることです。スレッドは、独自のキー値を通じてこのグローバル データ グループにアクセスします。この一意のキー値は、PHP5 でグローバル変数を使用する必要があるすべての関数に渡す必要がありますが、PHP7 では、この渡し方法はフレンドリーではなく、いくつかの問題があると考えられています。したがって、このキー値を保存するには、スレッド固有のグローバル変数を使用してみてください。

3. パラメータの戻り値の型を指定する

PHP 言語の非常に重要な機能は「弱い型付け」です。 "。これにより、PHP プログラムの作成が非常に簡単になります。

PHP7 は、オプションで型定義をサポートします。さらに、この命令が実行されると、 switch 命令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;
};
まず第一に、この構造体のサイズは 24 バイトです (64 ビット システム上)。この zval.value 共用体を詳しく見てみましょう。zend_object_value は最大のロングボードであり、値全体が発生します。結局のところ、IS_OBJECT は最も一般的に使用される型ではないため、これは移動してポインタに置き換えるなど、簡単に最適化できるはずです。

#2 番目に、この構造体の各フィールドには明確な意味があり、カスタム フィールドは予約されていません。その結果、PHP5 時代に多くの最適化を行う場合、zval に関連するいくつかの情報を保存する必要があります。 zval を拡張するには、他の構造マッピング、または外部パッケージ化とパッチを使用する必要があります。たとえば、5.3 では、特に循環参照を解決するために新しい GC が導入されました。次の比較的ハックなアプローチを採用してはなりません

3 番目に、PHP の zval のほとんどは値によって渡され、書き込み時に値がコピーされます。ただし、オブジェクトとリソースの 2 つの例外があります。これらは常に参照によって渡されます。 , したがって、これは問題を引き起こします. zval の参照カウントに加えて、オブジェクトとリソースには、メモリを確実にリサイクルできるようにするためのグローバル参照カウントも必要です. したがって、PHP5 の時代では、オブジェクトを例にとると、2 つの参照カウントがあります参照カウントのセット。1 つは zval にあり、もう 1 つは 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;
}

6、hashtable 的变化

7、执行器

8、新的参数解析方式

PHP5  对应的参数解析 zend_parse_parament,

PHP7对应的参数解析:fast_zpp  

以上がphp7 と PHP5 の新機能とパフォーマンスの最適化を見てみましょう。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。