The existing code makes copies of every byte it hashes.
When passed a large chunk of memory, Write and WriteString
can skip the copying and initSeed for most of it.
To ensure that Write, WriteByte, and WriteString continue to
generate output that depends only on the sequence of bytes,
expand the grouping test to include WriteString and interleaved calls.
Also, make the test process a lot more data, to ensure that
Write* handled full buffers correctly.
name old time/op new time/op delta
Hash8Bytes-8 17.1ns ± 3% 16.5ns ± 2% -3.26% (p=0.000 n=29+27)
Hash320Bytes-8 74.9ns ± 2% 58.5ns ± 2% -21.86% (p=0.000 n=30+29)
Hash1K-8 246ns ± 3% 195ns ± 1% -20.82% (p=0.000 n=29+30)
Hash8K-8 1.87µs ± 2% 1.59µs ± 2% -15.04% (p=0.000 n=26+30)
name old speed new speed delta
Hash8Bytes-8 468MB/s ± 3% 484MB/s ± 2% +3.36% (p=0.000 n=29+27)
Hash320Bytes-8 4.28GB/s ± 2% 5.47GB/s ± 2% +27.97% (p=0.000 n=30+29)
Hash1K-8 4.17GB/s ± 3% 5.26GB/s ± 1% +26.28% (p=0.000 n=29+30)
Hash8K-8 4.38GB/s ± 2% 5.16GB/s ± 2% +17.70% (p=0.000 n=26+30)
Updates #42710
Change-Id: If3cdec1580ffb3e36fab9865e5a9d089c0a34bec
Reviewed-on: https://go-review.googlesource.com/c/go/+/278758
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Add note about using per-use seeds.
Delete "collision-resistant but" in:
> The hash functions are collision-resistant but not cryptographically secure.
"Collision-resistant" has a precise cryptographic meaning that is
incompatible with "not cryptographically secure".
All that is really meant by it here here is "it's a good hash function",
which should be established already.
Also delete:
> The hash value of a given byte sequence is consistent within a
> single process, but will be different in different processes.
This was added for its final clause in response to #37040,
but "The hash value of a given byte sequence" is by design not a
concept in this package. Only "... of a given seed and byte sequence".
And seeds cannot be shared between processes, so again by design
you can't even set up the appropriate first half of the sentence
to say the second half.
Change-Id: I2c02bee0e804ef3b120cb4752bf89e60f3f5ff5d
Reviewed-on: https://go-review.googlesource.com/c/go/+/255968
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Test all the paths by which a Hash picks its seed.
Make sure they all behave identically to a preset seed.
Change-Id: I2f7950857697f2f07226b96655574c36931b2aae
Reviewed-on: https://go-review.googlesource.com/c/go/+/220686
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Vladimir Evgrafov <evgrafov.vladimir@gmail.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Hash initializes seed on the first usage of seed or state with initSeed.
initSeed uses SetSeed which discards accumulated data.
This causes hash to return different sums for the same data in the first use
and after reset.
This CL fixes this issue by separating the seed set from data discard.
Fixes#37315
Change-Id: Ic7020702c2ce822eb700af462e37efab12f72054
GitHub-Last-Rev: 48b2f963e8
GitHub-Pull-Request: golang/go#37328
Reviewed-on: https://go-review.googlesource.com/c/go/+/220259
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This allows maphash.Hash to be allocated on the stack for typical uses.
Fixes#35636
Change-Id: I8366507d26ea717f47a9fb46d3bd69ba799845ac
Reviewed-on: https://go-review.googlesource.com/c/go/+/207444
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This CL makes these changes to the hash/maphash API to make it fit a bit
more into the standard library:
- Move some of the package doc onto type Hash, so that `go doc maphash.Hash` shows it.
- Instead of having identical AddBytes and Write methods,
standardize on Write, the usual name for this function.
Similarly, AddString -> WriteString, AddByte -> WriteByte.
- Instead of having identical Hash and Sum64 methods,
standardize on Sum64 (for hash.Hash64). Dropping the "Hash" method
also helps because Hash is usually reserved to mean the state of a
hash function (hash.Hash etc), not the hash value itself.
- Make an uninitialized hash.Hash auto-seed with a random seed.
It is critical that users not use the same seed for all hash functions
in their program, at least not accidentally. So the Hash implementation
must either panic if uninitialized or initialize itself.
Initializing itself is less work for users and can be done lazily.
- Now that the zero hash.Hash is useful, drop maphash.New in favor of
new(maphash.Hash) or simply declaring a maphash.Hash.
- Add a [0]func()-typed field to the Hash so that Hashes cannot be compared.
(I considered doing the same for Seed but comparing seeds seems OK.)
- Drop the integer argument from MakeSeed, to match the original design
in golang.org/issue/28322. There is no point to giving users control
over the specific seed bits, since we want the interpretation of those
bits to be different in every different process. The only thing users
need is to be able to create a new random seed at each call.
(Fixes a TODO in MakeSeed's public doc comment.)
This API is new in Go 1.14, so these changes do not violate the compatibility promise.
Fixes#35060.
Fixes#35348.
Change-Id: Ie6fecc441f3f5ef66388c6ead92e875c0871f805
Reviewed-on: https://go-review.googlesource.com/c/go/+/205069
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Keith Randall <khr@golang.org>