PHP での配列ハッシュ関数の実装
今日は、PHP で変数を実装する方法を確認して学習しました。ソース コードを参照したところ、PHP のすべてのデータ型は共用体を介して格納されていることがわかりました。
PHP 言語は弱い型指定言語であり、その実装は変数の型と値を記録することによって管理されます。
?
PHP で最もよく使われるのは配列です。では、配列はどのように実装されるのでしょうか?
PHP では、配列はハッシュテーブルを介して実装されます。この方法では、ハッシュの競合の問題を解決するために連鎖メソッドが使用されます。この方法で、配列要素を見つける複雑さは最悪の場合でも O(N)、1 になります。最良の場合。
?
文字列のハッシュ値の計算方法は次のとおりです。参考までにソースコードを抜粋します。
追記: 次の関数については、まだ不明な点が 2 つあります:
1. ハッシュ = 5381 を設定する理由?
2. これは効率化のためのステップ=8のループ方法ですか?
?
static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength) { register ulong hash = 5381; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //此处初始值的设置有什么玄机么? /* variant with the hash unrolled eight times */ for (; nKeyLength >= 8; nKeyLength -= 8) { ? ? ? ? ? ? ? ? ? ? ? ? //这种step=8的方式是为何? hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; ? ? ? ? ? ? ? ? ? ? ? ? //比直接*33要快 hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; hash = ((hash << 5) + hash) + *arKey++; } switch (nKeyLength) { case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? //此处是将剩余的字符hash case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ ? ? ? ? ? ? ? ? ? ? case 1: hash = ((hash << 5) + hash) + *arKey++; break; case 0: break; EMPTY_SWITCH_DEFAULT_CASE() } return hash; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//返回hash值 }