Open adonovan opened 1 month ago
Change https://go.dev/cl/612496 mentions this issue: go/types/typeutil: make Hasher stateless
@timothy-king do you mean to use Comparable for hashPtr, rather than relying on a non-moving GC?
@timothy-king do you mean to use Comparable for hashPtr, rather than relying on a non-moving GC?
maphash.Comparable does the same thing as our code (reflect.Value.Pointer). The only difference is that, being std code, it is morally permitted to assume a non-moving GC, but once the updated https://github.com/golang/go/issues/67161 lands, we can use types.Hash
, which will have equal moral license.
Thinking about https://github.com/golang/go/issues/67161, I wanted to know whether the the new API should include Hasher. It complicates the API because it turns reads (lookups in typeutil.Map) into writes (memoization of hash values). Is it an effective optimization, or does it increase memory contention (and potentially the need for locking)?
I gutted its implementation, removing both memoization maps, and simplifying the implementation of Hasher.hashPtr to just
reflect.ValueOf(ptr).Pointer()
(which assumes a non-moving GC) and Hasher.hashTypeParam to a hash of t.Index(), making Hasher a stateless empty struct. Then I ran BenchmarkRTA, modified to analyze all of gopls, not just net/http.The results:
It is slightly faster and has lower variance. Whatever problems a stateful Hasher once solved, we have no further need for it.
Let's make it an empty struct, and disregard it when considering #67161.
@timothy-king @findleyr