PHP は人気のあるプログラミング言語であり、特に Web 開発で広く使用されています。 PHP では、配列はデータの保存と操作に使用できる非常に重要なデータ構造です。ただし、多くの PHP 開発者は配列の内部実装を理解していません。この記事では、開発者が PHP 配列をより効果的に使用および最適化できるように、PHP 配列の基礎となる実装について詳しく説明します。
1. PHP 配列の基本概要
PHP では、配列とは、あらゆる種類のデータを格納できる、順序付けされていない可変長のデータ コンテナーです。 PHP 配列には、インデックス付き配列と連想配列の 2 種類があります。インデックス付き配列は要素にアクセスするためのインデックスとして数値を使用しますが、連想配列は要素にアクセスするためのインデックスとして文字列を使用します。 2 種類の配列がどのように定義されるかを次に示します:
$indexArray = array('apple', 'orange', 'banana'); $assocArray = array('name' => 'Tom', 'age' => 18);
配列要素にアクセスする方法は次のとおりです:
$indexArray[0] // 访问索引为0的元素 $assocArray['name'] // 访问键为'name'的元素
配列は要素の追加、変更、削除などの操作もサポートしています:
$indexArray[] = 'grape'; // 添加一个新元素 $indexArray[0] = 'cherry'; // 修改索引为0的元素 unset($indexArray[1]); // 删除索引为1的元素
2. PHP 配列の内部実装
PHP 配列の基礎となる実装は HashTable です。 HashTable はハッシュ テーブルであり、その機能はキーと値のペアを特定のインデックスにマップすることです。 PHP 配列は C 言語構造を使用して HashTable を実装します。その構造は次のとおりです:
typedef struct _hashtable { unsigned int nTableMask; Bucket *arBuckets; unsigned int nNumOfElements; unsigned int nNextFreeElement; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection; #ifdef ZEND_HASH_STATISTICS ulong nTableSize; ulong nTableMaskUsed; uint nNumOfCollisions; uint nNumOfChecks; uint nNumOfInserts; uint nNumOfInconsistentInserts; uint nNumOfFailedExpands; #endif/*ZEND_HASH_STATISTICS*/ } HashTable;
上記の構造において、nTableMask はハッシュ テーブルのサイズを表し、arBuckets はすべてのデータを格納する Bucket 配列です。バケットは、ハッシュの競合を解決するために使用されるリンク リスト構造です。 nNumOfElements はハッシュ テーブル内の要素の数を表し、nNextFreeElement は次の空き要素のインデックスを表します。 pDestructor は、要素が削除されたときにその値を処理するコールバック関数です。 persistent は、ハッシュ テーブルが永続的であるかどうかを示します。 nApplyCount と bApplyProtection は、同時アクセスをサポートするために使用されます。 ZEND_HASH_STATISTICS は、デバッグに使用される統計情報です。
PHP 配列の基礎となる実装は、次の 3 つの部分に分けることができます。
ハッシュ関数は、配列のキーをハッシュにマップします。テーブル内のインデックス。 PHP 配列は、ハッシュが可能な限り均等になるように、さまざまなハッシュ関数を使用します。ハッシュ関数は通常、配列キーを使用してハッシュ値を計算し、ハッシュ テーブルのサイズに収まるように値を圧縮します。 PHP 配列で使用されるハッシュ関数は次のとおりです。
ZEND_HASH_FUNC(joaat) ZEND_HASH_FUNC(fnv) ZEND_HASH_FUNC(djb2) ZEND_HASH_FUNC(php) ZEND_HASH_FUNC(sha1)
PHP 配列のアクセス操作には、通常、クエリ、追加、変更、およびクエリなどの操作が含まれます。要素を削除しています。要素にアクセスするとき、PHP 配列はまずハッシュ関数を使用して要素のハッシュ値を計算し、次にこのハッシュ値に基づいて対応するバケットを見つけます。このバケットにすでに要素がある場合、PHP 配列はリンク リスト全体を走査して、対応する要素を見つけます。要素が見つかった場合は、その値が直接返されます。それ以外の場合は、nNextFreeElement を使用して新しい要素を挿入し、適切なバケット上に新しいバケットを作成して、リンクされたリストの末尾に新しい要素を挿入します。
PHP 配列のガベージ コレクションは、通常、デストラクターを通じて実装されます。要素が削除されるとき、要素の値が PHP オブジェクトの場合は、そのデストラクターが呼び出されます。このデストラクターは、このオブジェクトによって占有されているメモリを解放する役割を果たします。この配列が永続的に保存されている場合、PHP はスクリプトの実行後にその配列をメモリから削除しませんが、PHP プロセス全体が終了するまで待ってから配列を破棄します。
3. PHP 配列のパフォーマンスの最適化
配列は PHP で非常に一般的に使用されるデータ構造であり、そのパフォーマンスはコードの品質と設計に密接に関係しています。以下は、PHP 配列のパフォーマンスに関する最適化の提案です:
配列内の要素にアクセスするには、通常、ハッシュ値の計算とリンク リストの走査が必要です。これらの操作には時間がかかります。同じ要素に複数回アクセスする必要がある場合、その値を変数に直接保存すると、ハッシュ値の計算やリンク リストの複数回の走査を避けることができます。
要素にアクセス、変更、または追加するときは、配列操作の数を最小限に抑えるようにしてください。変数を使用して配列内の要素を置き換えて計算を実行し、最後に配列に対して代入演算を実行します。
unset() を使用して配列内の要素を削除する場合は、インデックスを指定してください削除される。このように、PHP 配列は最初からすべての要素を走査する必要がなく、削除する要素を直接見つけることができます。
インデックス付き配列と連想配列の基本的な実装原理は異なり、それぞれの配列型を使用することでパフォーマンスが向上します。
以上がPHP配列の最下層はどのように実装されているのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。