PHP中使用最多的非Array莫屬了,那Array是如何?的?在PHP內部Array通過一個hashtable來實現,其中使用連結法解決hash衝突的問題,這樣最壞情況下,尋找Array元素的複雜度為O(N),最好則為1.
而其計算字串hash值的方法如下,將源碼摘出來以供查備:
複製代碼 代碼如下: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值
}
ps:對於以下函數,仍有兩點不明:
hash = 5381設定的理由?
這種step=8的迴圈方式是為了效率嗎?