ハッシュテーブル
PHP 7ではハッシュテーブルも高速化されています。ハッシュテーブルとバケットの構造体を比較してみましょう。まずはPHP 5からです。
typedef struct bucket {
ulong h;
uint nKeyLength;
void *pData;
void *pDataPtr;
struct bucket *pListNext;
struct bucket *pListLast;
struct bucket *pNext;
struct bucket *pLast;
char arKey[1];
} Bucket;
typedef struct _hashtable {
uint nTableSize;
uint nTableMask;
uint nNumOfElements;
ulong nNextFreeElement;
Bucket *pInternalPointer;
Bucket *pListHead;
Bucket *pListTail;
Bucket **arBuckets;
dtor_func_t pDestructor;
zend_bool persistent;
unsigned char nApplyCount;
zend_bool bApplyProtection;
} HashTable;
以上のとおり、HashTableは72バイト、Bucketも72バイトあります。続いてPHP 7です。
typedef struct _Bucket {
zval val;
zend_ulong h;
zend_string *key;
} Bucket;
typedef struct _HashTable {
union {
struct {
zend_uchar flags;
zend_uchar nApplyCount;
uint16_t reserve;
} v;
uint32_t flags;
} u;
uint32_t nTableSize;
uint32_t nTableMask;
uint32_t nNumUsed;
uint32_t nNumOfElements;
uint32_t nInternalPointer;
zend_long nNextFreeElement;
Bucket *arData;
uint32_t *arHash;
dtor_func_t pDestructor;
} HashTable;
HashTableは56バイト、Bucketは32バイトに大きく減っています。サイズが少なくなっただけではありません。PHP 7ではzvalの実体をもっているので、動的にzvalを確保することがなく、オーバーヘッドが生じません。さらに、ハッシュテーブルの構造をみてみましょう。
PHP 5ではpListHeadからBucketを動的に確保してチェーンをつないでいましたが、PHP 7ではarDataの先には連続したBucketが確保されています。Bucketを動的に確保することがないので、オーバーヘッドが生じません。ポインタをたどる必要がないので、Bucketを走査する処理も明らかに早くなります。
- 修正履歴
-
- 2015/03/24 10:11 リード文がおかしくなっていたため、修正いたしました。
この記事は参考になりましたか?
- Yahoo! JAPAN 黒帯シリーズ連載記事一覧
- この記事の著者
-
蒋池 東龍(ヤフー株式会社)(コモイケ トウリュウ)
ヤフー株式会社 COO 事業推進本部 プロダクト開発 黒帯 PHPコア1999年セガ(当時セガ・エンタープライゼス)に新卒入社しプログラマーとして「ジェットセットラジオ」「Jリーグ スペクタクルサッカー」「J.LEAGUEプロサッカークラブをつくろう!」の開発に従事。2004年10月ヤフー株式会社入...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
