ホームページ  >  記事  >  バックエンド開発  >  PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)

藏色散人
藏色散人転載
2021-06-10 15:00:222939ブラウズ

今回は「PHP8の基盤となるカーネルソースコードの解析 - 配列(3)」を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

おすすめ関連記事: 「PHP8 の基礎となるカーネル ソース コードの分析 - 配列 (1) 」 「PHP8 の基礎となるカーネル ソース コードの分析 - 配列 (2) " PHP8 の基礎となるカーネル ソース コードの分析 - 配列 (4) >>

上記で、PHP における配列の基本構造の実装とインデックスの構成原理が完全に分析されました。

_Bucket と _zend_array の 2 つの構造に依存する

o(1) の複雑さはハッシュ関数によって実現されます

しかし、バケットの前にインデックス配列があります。私が多くの落とし穴を経験した時点で、このインデックス配列を理解していました。

下の図は $c =array('x'=>1,'y'=>2,' z'=>3,'a '=>0); 配列 c のバケット構造

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)

#上記の通り、packed_arrayの場合インデックス配列は常に2であり、機能しません

理由パックされている場合、キーは直接nullですハッシュ値を計算する必要はありません。このインデックス配列は、h 値をすばやく見つけるためにのみ使用されます

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)
$a =array(1,2,3)bucket
typedef struct _Bucket {
zval              val;   //数组的值 ( 复习下 zval只有16个字节)
zend_ulong         h;     // key的 h  值
zend_string      *key;      //当数组为 hash_array时候 会用到 也就是 key的值  
} Bucket;

should be Packedarray 現時点では val が学習のアイデアに影響を与えないようにしてください。h の値は配列の位置の添字と等しくなります (配列はすべて 0 から始まるため、添字も同様です) 0から始まります)。たとえば、前述の
$b =array(1=>'a',3=>'b',5=>'c'); ここで、配列 b も Packed_array であり、次の構造を持ちます。

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)

配列 b は 0 番目の配列の値を定義していないため無効です。 1] は 'a' ここでは、画像上で val=a(zval) と直接マークしました。実際には、16 バイトの zval の string 型の zend_string です。ここでは、以前学習した gc を使用します。たくさんあります。すべての PHP カーネル ソース コードには無限の入れ子人形が含まれており、過去を振り返り、新しいことを学びます。

戻ってきて、それについて話してください$c =array('x'=>1,'y'=>2,'z'=>3,'a'=>0);

構造は次のとおりです

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)

この h 値は非常に大きいため、ハッシュ値がわかりませんtime33 までの key を使用して計算されます。なぜハッシュ値と呼ばれるのでしょうか? time33 を通じて計算された h 値をハッシュ テーブルに形成したものだと思います

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)
#ハッシュ テーブルは主に、記憶要素の配列とハッシュ関数の 2 つの部分で構成されます。単純なハッシュ関数では剰余法を使用できます。たとえば、ハッシュ テーブルのサイズが 8 の場合、ハッシュ テーブルが配列を初期化するときに 8 要素のスペースを割り当てます。キーのハッシュ コードをたどって分割します。得られる値は、配列内の要素のインデックスです。このようにして、キーをストレージ配列内の特定の場所にマッピングできます

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)
#ただし、キーを直接実装するには問題があります。上記の方法で配列: 配列内の要素の位置はランダムであり、順序付けされていません

PHP の配列は順序付けされているため、ハッシュ関数と要素配列の間にインデックス テーブルが追加されます。 table も配列です。サイズは要素が格納されている配列と同じです。ただし、格納される要素の型は常に整数であり、要素配列の添字を実際に格納される配列に保存するために使用されます。要素は実際に格納される配列に順番に挿入され、配列の添字は次に従って計算されます。ハッシュ関数. 位置は新しく追加されたインデックスに保存されます。

PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)#最初のステップは、4 を計算し、インデックス テーブルで -4 を見つけることです。これは 0 番目の配列なので、それを配置します。インデックス テーブルの -4 番目の配列の値が 0 に設定され、その後、実数配列テーブルの 0 番目の要素が、ハッシュ テーブル内のさまざまな要素の実際に割り当てられた zval

key に設定されます。計算されるハッシュ値は、同じインデックス テーブル内の添え字を指す場合にハッシュの競合が発生することと同じです。インデックス テーブルには 1 つの要素しか格納できないため、PHP はジッパー メソッドを使用してハッシュの競合を実現し、リンクされたリスト内の値を取得します。以下の図「PHP7 カーネル分析 - Qin Peng」を参照してください。

##通常の状況PHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)val.u2.next
値は -1 です。これは、初期値とのハッシュ競合が発生すると、ここでの値は競合前の配列の真の位置を指すことを意味します。

▏この記事は、原著者 PHP Cui Xuefeng の同意を得て、PHP 中国語 Web サイトに掲載されました。元のアドレス: https://zhuanlan.zhihu.com/p/360952022

以上がPHP8 の基礎となるカーネル ソース コードの解析 - 配列 (3)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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