1
0
mirror of https://github.com/golang/go synced 2024-10-03 00:31:22 -06:00

hash: more efficient memory allocation

Feed append the complete content at once.

BenchmarkAdler32KB       1000000              2534 ns/op         404.05 MB/s
BenchmarkCrc32KB          500000              4757 ns/op         215.26 MB/s
BenchmarkCrc64KB          500000              4769 ns/op         214.70 MB/s
BenchmarkFnv32KB         1000000              2417 ns/op         423.64 MB/s
BenchmarkFnv32aKB        1000000              2408 ns/op         425.23 MB/s
BenchmarkFnv64KB          500000              4262 ns/op         240.21 MB/s
BenchmarkFnv64aKB         500000              4234 ns/op         241.83 MB/s

R=iant, rsc, r, minux.ma
CC=golang-dev
https://golang.org/cl/5937053
This commit is contained in:
Pascal S. de Kloe 2012-04-10 15:15:39 -04:00 committed by Russ Cox
parent 7056ec6bfd
commit 9feddd0bae
8 changed files with 55 additions and 89 deletions

View File

@ -75,11 +75,7 @@ func (d *digest) Sum32() uint32 { return finish(d.a, d.b) }
func (d *digest) Sum(in []byte) []byte { func (d *digest) Sum(in []byte) []byte {
s := d.Sum32() s := d.Sum32()
in = append(in, byte(s>>24)) return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
return in
} }
// Checksum returns the Adler-32 checksum of data. // Checksum returns the Adler-32 checksum of data.

View File

@ -5,7 +5,6 @@
package adler32 package adler32
import ( import (
"bytes"
"io" "io"
"testing" "testing"
) )
@ -63,15 +62,19 @@ func TestGolden(t *testing.T) {
} }
} }
func BenchmarkGolden(b *testing.B) { func BenchmarkAdler32KB(b *testing.B) {
b.StopTimer() b.SetBytes(1024)
c := New() data := make([]byte, 1024)
var buf bytes.Buffer for i := range data {
for _, g := range golden { data[i] = byte(i)
buf.Write([]byte(g.in))
} }
b.StartTimer() h := New()
in := make([]byte, 0, h.Size())
b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
c.Write(buf.Bytes()) h.Reset()
h.Write(data)
h.Sum(in)
} }
} }

View File

@ -123,11 +123,7 @@ func (d *digest) Sum32() uint32 { return d.crc }
func (d *digest) Sum(in []byte) []byte { func (d *digest) Sum(in []byte) []byte {
s := d.Sum32() s := d.Sum32()
in = append(in, byte(s>>24)) return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
return in
} }
// Checksum returns the CRC-32 checksum of data // Checksum returns the CRC-32 checksum of data

View File

@ -82,16 +82,18 @@ func TestGolden(t *testing.T) {
} }
func BenchmarkCrc32KB(b *testing.B) { func BenchmarkCrc32KB(b *testing.B) {
b.StopTimer() b.SetBytes(1024)
data := make([]uint8, 1024) data := make([]byte, 1024)
for i := 0; i < 1024; i++ { for i := range data {
data[i] = uint8(i) data[i] = byte(i)
} }
c := NewIEEE() h := NewIEEE()
b.StartTimer() in := make([]byte, 0, h.Size())
b.SetBytes(int64(len(data)))
b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
c.Write(data) h.Reset()
h.Write(data)
h.Sum(in)
} }
} }

View File

@ -79,15 +79,7 @@ func (d *digest) Sum64() uint64 { return d.crc }
func (d *digest) Sum(in []byte) []byte { func (d *digest) Sum(in []byte) []byte {
s := d.Sum64() s := d.Sum64()
in = append(in, byte(s>>56)) return append(in, byte(s>>56), byte(s>>48), byte(s>>40), byte(s>>32), byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
in = append(in, byte(s>>48))
in = append(in, byte(s>>40))
in = append(in, byte(s>>32))
in = append(in, byte(s>>24))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
return in
} }
// Checksum returns the CRC-64 checksum of data // Checksum returns the CRC-64 checksum of data

View File

@ -64,15 +64,18 @@ func TestGolden(t *testing.T) {
} }
func BenchmarkCrc64KB(b *testing.B) { func BenchmarkCrc64KB(b *testing.B) {
b.StopTimer() b.SetBytes(1024)
data := make([]uint8, 1024) data := make([]byte, 1024)
for i := 0; i < 1024; i++ { for i := range data {
data[i] = uint8(i) data[i] = byte(i)
} }
c := New(tab) h := New(tab)
b.StartTimer() in := make([]byte, 0, h.Size())
b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
c.Write(data) h.Reset()
h.Write(data)
h.Sum(in)
} }
} }

View File

@ -111,44 +111,20 @@ func (s *sum64a) BlockSize() int { return 1 }
func (s *sum32) Sum(in []byte) []byte { func (s *sum32) Sum(in []byte) []byte {
v := uint32(*s) v := uint32(*s)
in = append(in, byte(v>>24)) return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
in = append(in, byte(v>>16))
in = append(in, byte(v>>8))
in = append(in, byte(v))
return in
} }
func (s *sum32a) Sum(in []byte) []byte { func (s *sum32a) Sum(in []byte) []byte {
v := uint32(*s) v := uint32(*s)
in = append(in, byte(v>>24)) return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
in = append(in, byte(v>>16))
in = append(in, byte(v>>8))
in = append(in, byte(v))
return in
} }
func (s *sum64) Sum(in []byte) []byte { func (s *sum64) Sum(in []byte) []byte {
v := uint64(*s) v := uint64(*s)
in = append(in, byte(v>>56)) return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
in = append(in, byte(v>>48))
in = append(in, byte(v>>40))
in = append(in, byte(v>>32))
in = append(in, byte(v>>24))
in = append(in, byte(v>>16))
in = append(in, byte(v>>8))
in = append(in, byte(v))
return in
} }
func (s *sum64a) Sum(in []byte) []byte { func (s *sum64a) Sum(in []byte) []byte {
v := uint64(*s) v := uint64(*s)
in = append(in, byte(v>>56)) return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
in = append(in, byte(v>>48))
in = append(in, byte(v>>40))
in = append(in, byte(v>>32))
in = append(in, byte(v>>24))
in = append(in, byte(v>>16))
in = append(in, byte(v>>8))
in = append(in, byte(v))
return in
} }

View File

@ -11,8 +11,6 @@ import (
"testing" "testing"
) )
const testDataSize = 40
type golden struct { type golden struct {
sum []byte sum []byte
text string text string
@ -134,34 +132,34 @@ func testIntegrity(t *testing.T, h hash.Hash) {
} }
} }
func Benchmark32(b *testing.B) { func BenchmarkFnv32KB(b *testing.B) {
benchmark(b, New32()) benchmarkKB(b, New32())
} }
func Benchmark32a(b *testing.B) { func BenchmarkFnv32aKB(b *testing.B) {
benchmark(b, New32a()) benchmarkKB(b, New32a())
} }
func Benchmark64(b *testing.B) { func BenchmarkFnv64KB(b *testing.B) {
benchmark(b, New64()) benchmarkKB(b, New64())
} }
func Benchmark64a(b *testing.B) { func BenchmarkFnv64aKB(b *testing.B) {
benchmark(b, New64a()) benchmarkKB(b, New64a())
} }
func benchmark(b *testing.B, h hash.Hash) { func benchmarkKB(b *testing.B, h hash.Hash) {
b.ResetTimer() b.SetBytes(1024)
b.SetBytes(testDataSize) data := make([]byte, 1024)
data := make([]byte, testDataSize)
for i := range data { for i := range data {
data[i] = byte(i + 'a') data[i] = byte(i)
} }
in := make([]byte, 0, h.Size())
b.StartTimer() b.ResetTimer()
for todo := b.N; todo != 0; todo-- { for i := 0; i < b.N; i++ {
h.Reset() h.Reset()
h.Write(data) h.Write(data)
h.Sum(nil) h.Sum(in)
} }
} }