diff --git a/AUTHORS.md b/AUTHORS.md index 63bd4ad..56c7518 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,3 +1,4 @@ ## AUTHORS +- [Dominik Honnef](https://github.com/dominikh) dominik@honnef.co - [Dong-hee Na](https://github.com/corona10/) donghee.na92@gmail.com - [Gustavo Brunoro](https://github.com/brunoro/) git@hitnail.net diff --git a/hashcompute_test.go b/hashcompute_test.go index 5502098..47e6c71 100644 --- a/hashcompute_test.go +++ b/hashcompute_test.go @@ -97,3 +97,21 @@ func TestHashCompute(t *testing.T) { } } } + +func BenchmarkDistanceIdentical(b *testing.B) { + h1 := &ImageHash{hash: 0xe48ae53c05e502f7} + h2 := &ImageHash{hash: 0xe48ae53c05e502f7} + + for i := 0; i < b.N; i++ { + h1.Distance(h2) + } +} + +func BenchmarkDistanceDifferent(b *testing.B) { + h1 := &ImageHash{hash: 0xe48ae53c05e502f7} + h2 := &ImageHash{hash: 0x678be53815e510f7} // 8 bits flipped + + for i := 0; i < b.N; i++ { + h1.Distance(h2) + } +} diff --git a/imagehash.go b/imagehash.go index 785a34b..da0af93 100644 --- a/imagehash.go +++ b/imagehash.go @@ -42,17 +42,11 @@ func (h *ImageHash) Distance(other *ImageHash) (int, error) { return -1, errors.New("Image hashes's kind should be identical") } - diff := 0 lhash := h.GetHash() rhash := other.GetHash() hamming := lhash ^ rhash - for hamming != 0 { - diff += int(hamming & 1) - hamming >>= 1 - } - - return diff, nil + return popcnt(hamming), nil } // GetHash method returns a 64bits hash value. diff --git a/imagehash18.go b/imagehash18.go new file mode 100644 index 0000000..e8d3fd6 --- /dev/null +++ b/imagehash18.go @@ -0,0 +1,13 @@ +// +build !go1.9 + +package goimagehash + +func popcnt(x uint64) int { + diff := 0 + for x != 0 { + diff += int(x & 1) + x >>= 1 + } + + return diff +} diff --git a/imagehash19.go b/imagehash19.go new file mode 100644 index 0000000..c1d47be --- /dev/null +++ b/imagehash19.go @@ -0,0 +1,9 @@ +// +build go1.9 + +package goimagehash + +import ( + "math/bits" +) + +func popcnt(x uint64) int { return bits.OnesCount64(x) }