diff options
| author | Robert Griesemer <gri@golang.org> | 2017-02-18 11:14:35 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2017-02-19 18:50:48 +0000 |
| commit | 177dfba1120d2d5976bb5fb5a68bf20bb6ca9ada (patch) | |
| tree | c370d8bd9c6d7fb2db3e49707b5c73a0854d676e /src/math/bits/bits_test.go | |
| parent | d9a19f86fb5297aee62242ad14b6a69d2c990a79 (diff) | |
| download | go-177dfba1120d2d5976bb5fb5a68bf20bb6ca9ada.tar.xz | |
math/bits: faster OnesCount
Using some additional suggestions per "Hacker's Delight".
Added documentation and extra tests.
Measured on 1.7 GHz Intel Core i7, running macOS 10.12.3.
benchmark old ns/op new ns/op delta
BenchmarkOnesCount-4 7.34 5.38 -26.70%
BenchmarkOnesCount8-4 2.03 1.98 -2.46%
BenchmarkOnesCount16-4 2.56 2.50 -2.34%
BenchmarkOnesCount32-4 2.98 2.39 -19.80%
BenchmarkOnesCount64-4 4.22 2.96 -29.86%
Change-Id: I566b0ef766e55cf5776b1662b6016024ebe5d878
Reviewed-on: https://go-review.googlesource.com/37223
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/math/bits/bits_test.go')
| -rw-r--r-- | src/math/bits/bits_test.go | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/src/math/bits/bits_test.go b/src/math/bits/bits_test.go index c74e58ebde..50045c246e 100644 --- a/src/math/bits/bits_test.go +++ b/src/math/bits/bits_test.go @@ -232,48 +232,61 @@ func BenchmarkTrailingZeros64(b *testing.B) { } func TestOnesCount(t *testing.T) { + var x uint64 + for i := 0; i <= 64; i++ { + testOnesCount(t, x, i) + x = x<<1 | 1 + } + + for i := 64; i >= 0; i-- { + testOnesCount(t, x, i) + x = x << 1 + } + for i := 0; i < 256; i++ { - want := tab[i].pop for k := 0; k < 64-8; k++ { - x := uint64(i) << uint(k) - if x <= 1<<8-1 { - got := OnesCount8(uint8(x)) - if got != want { - t.Fatalf("OnesCount8(%#02x) == %d; want %d", x, got, want) - } - } + testOnesCount(t, uint64(i)<<uint(k), tab[i].pop) + } + } +} - if x <= 1<<16-1 { - got := OnesCount16(uint16(x)) - if got != want { - t.Fatalf("OnesCount16(%#04x) == %d; want %d", x, got, want) - } - } +func testOnesCount(t *testing.T, x uint64, want int) { + if x <= 1<<8-1 { + got := OnesCount8(uint8(x)) + if got != want { + t.Fatalf("OnesCount8(%#02x) == %d; want %d", x, got, want) + } + } - if x <= 1<<32-1 { - got := OnesCount32(uint32(x)) - if got != want { - t.Fatalf("OnesCount32(%#08x) == %d; want %d", x, got, want) - } - if UintSize == 32 { - got = OnesCount(uint(x)) - if got != want { - t.Fatalf("OnesCount(%#08x) == %d; want %d", x, got, want) - } - } + if x <= 1<<16-1 { + got := OnesCount16(uint16(x)) + if got != want { + t.Fatalf("OnesCount16(%#04x) == %d; want %d", x, got, want) + } + } + + if x <= 1<<32-1 { + got := OnesCount32(uint32(x)) + if got != want { + t.Fatalf("OnesCount32(%#08x) == %d; want %d", x, got, want) + } + if UintSize == 32 { + got = OnesCount(uint(x)) + if got != want { + t.Fatalf("OnesCount(%#08x) == %d; want %d", x, got, want) } + } + } - if x <= 1<<64-1 { - got := OnesCount64(uint64(x)) - if got != want { - t.Fatalf("OnesCount64(%#016x) == %d; want %d", x, got, want) - } - if UintSize == 64 { - got = OnesCount(uint(x)) - if got != want { - t.Fatalf("OnesCount(%#016x) == %d; want %d", x, got, want) - } - } + if x <= 1<<64-1 { + got := OnesCount64(uint64(x)) + if got != want { + t.Fatalf("OnesCount64(%#016x) == %d; want %d", x, got, want) + } + if UintSize == 64 { + got = OnesCount(uint(x)) + if got != want { + t.Fatalf("OnesCount(%#016x) == %d; want %d", x, got, want) } } } |
