javascript 关联数组使用什么样的散列 function/algorithm?
What kind of hashing function/algorithm does javascript associative array use?
我们了解到有许多不同的哈希算法 algorithms/functions,我很好奇 javascript(v8,如果实施很重要)使用了哪一个。
既然V8是开源的,你去源码:
这是 GetHash():https://github.com/v8/v8/blob/master/src/objects.cc#L903
而且,这里是一些不同类型的哈希函数:https://github.com/v8/v8-git-mirror/blob/bda7fb22465fc36d99b4053f0ef60cfaa8441209/src/utils.h#L347
而且,这看起来像是字符串的核心哈希计算:https://code.google.com/p/v8/source/browse/trunk/src/objects.cc?spec=svn6&r=6#3574
uint32_t String::ComputeHashCode(unibrow::CharacterStream* buffer,
int length) {
// Large string (please note large strings cannot be an array index).
if (length > kMaxMediumStringSize) return HashField(length, false);
// Note: the Jenkins one-at-a-time hash function
uint32_t hash = 0;
while (buffer->has_more()) {
uc32 r = buffer->GetNext();
hash += r;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
// Short string.
if (length <= kMaxShortStringSize) {
// Make hash value consistent with value returned from String::Hash.
buffer->Rewind();
uint32_t index;
hash = HashField(hash, ComputeArrayIndex(buffer, &index, length));
hash = (hash & 0x00FFFFFF) | (length << kShortLengthShift);
return hash;
}
// Medium string (please note medium strings cannot be an array index).
ASSERT(length <= kMaxMediumStringSize);
// Make hash value consistent with value returned from String::Hash.
hash = HashField(hash, false);
hash = (hash & 0x0000FFFF) | (length << kMediumLengthShift);
return hash;
}
可能值得一提的是,V8 尽可能避免对对象属性使用散列 table,更愿意将已知的 属性 引用编译为直接索引引用而不是 [=26] =]-time hash lookups for performance reasons (though this is only possible sometimes - depends on the code).
我们了解到有许多不同的哈希算法 algorithms/functions,我很好奇 javascript(v8,如果实施很重要)使用了哪一个。
既然V8是开源的,你去源码:
这是 GetHash():https://github.com/v8/v8/blob/master/src/objects.cc#L903
而且,这里是一些不同类型的哈希函数:https://github.com/v8/v8-git-mirror/blob/bda7fb22465fc36d99b4053f0ef60cfaa8441209/src/utils.h#L347
而且,这看起来像是字符串的核心哈希计算:https://code.google.com/p/v8/source/browse/trunk/src/objects.cc?spec=svn6&r=6#3574
uint32_t String::ComputeHashCode(unibrow::CharacterStream* buffer,
int length) {
// Large string (please note large strings cannot be an array index).
if (length > kMaxMediumStringSize) return HashField(length, false);
// Note: the Jenkins one-at-a-time hash function
uint32_t hash = 0;
while (buffer->has_more()) {
uc32 r = buffer->GetNext();
hash += r;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
// Short string.
if (length <= kMaxShortStringSize) {
// Make hash value consistent with value returned from String::Hash.
buffer->Rewind();
uint32_t index;
hash = HashField(hash, ComputeArrayIndex(buffer, &index, length));
hash = (hash & 0x00FFFFFF) | (length << kShortLengthShift);
return hash;
}
// Medium string (please note medium strings cannot be an array index).
ASSERT(length <= kMaxMediumStringSize);
// Make hash value consistent with value returned from String::Hash.
hash = HashField(hash, false);
hash = (hash & 0x0000FFFF) | (length << kMediumLengthShift);
return hash;
}
可能值得一提的是,V8 尽可能避免对对象属性使用散列 table,更愿意将已知的 属性 引用编译为直接索引引用而不是 [=26] =]-time hash lookups for performance reasons (though this is only possible sometimes - depends on the code).