How does go calculate a hash value for keys in a map?

How does go calculate a hash value for keys in a map?

ref

original

  1. The language spec doesn’t say, which means that it’s free to change at any time, or differ between implementations.

  2. The hash algorithm varies somewhat between types and platforms. As of now: On x86 (32 or 64 bit) if the CPU supports AES instructions, the runtime uses aeshash, a hash built on AES primitives, otherwise it uses a function “inspired by” xxHash and cityhash, but different from either. There are different variants for 32-bit and 64-bit systems. Most types use a simple hash of their memory contents, but floating-point types have code to ensure that 0 and -0 hash equally (since they compare equally) and NaNs hash randomly (since two NaNs are never equal). Since complex types are built from floats, their hashes are composed from the hashes of their two floating-point parts. And an interface’s hash is the hash of the value stored in the interface, and not the interface header itself.

  3. All of this stuff is in private functions, so no, you can’t access Go’s internal hash for a value in your own code.

  4. if two things compare equal with == they must have equal hashes (or maps wouldn’t work… this is also the reasoning behind all of the special cases I outlined above). That means that strings hash their bodies, not their headers. And structs compose the hashes of all of their fields. I can’t find the code actually implementing that, but the tests and the comparison rules make it clear.

summary

  1. 平台/体系结构相关, func hash绑定至_type.alg中, x86下且支持AES指令使用基于AES原语的aeshash, 否则…
  2. float的计算方式比较特殊, 由于IEEE-754.
  3. interface的哈希根据存储其中的hash value计算出, 而非头部
  4. string, struct 的哈希值由构成他们的域/字符计算得出, 而非头部
  5. golang定义的hash均为私有, 但可以通过==推断二者的hash value是否相等, 但注意 slice, map, func, 带有前面3者的array && struct不可比较
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy