Skip to content

Commit ad2b6de

Browse files
dominikhcorona10
authored andcommitted
Use bits.OnesCount64 when available
Benchmark on i7-2600k, which has the POPCNT instruction: name old time/op new time/op delta DistanceIdentical-8 5.08ns ± 0% 1.01ns ± 1% -80.07% (p=0.008 n=5+5) DistanceDifferent-8 81.5ns ± 2% 1.0ns ± 0% -98.76% (p=0.016 n=5+4) Benchmark on Cavium Octeon, a MIPS64 platform with no dedicated instruction: name old time/op new time/op delta DistanceIdentical-2 120ns ± 6% 144ns ± 5% +19.93% (p=0.008 n=5+5) DistanceDifferent-2 656ns ± 4% 144ns ± 4% -78.09% (p=0.008 n=5+5)
1 parent 7f23d56 commit ad2b6de

5 files changed

+42
-7
lines changed

AUTHORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
## AUTHORS
2+
- [Dominik Honnef](https://github.com/dominikh) [email protected]
23
- [Dong-hee Na](https://github.com/corona10/) [email protected]
34
- [Gustavo Brunoro](https://github.com/brunoro/) [email protected]

hashcompute_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,21 @@ func TestHashCompute(t *testing.T) {
9797
}
9898
}
9999
}
100+
101+
func BenchmarkDistanceIdentical(b *testing.B) {
102+
h1 := &ImageHash{hash: 0xe48ae53c05e502f7}
103+
h2 := &ImageHash{hash: 0xe48ae53c05e502f7}
104+
105+
for i := 0; i < b.N; i++ {
106+
h1.Distance(h2)
107+
}
108+
}
109+
110+
func BenchmarkDistanceDifferent(b *testing.B) {
111+
h1 := &ImageHash{hash: 0xe48ae53c05e502f7}
112+
h2 := &ImageHash{hash: 0x678be53815e510f7} // 8 bits flipped
113+
114+
for i := 0; i < b.N; i++ {
115+
h1.Distance(h2)
116+
}
117+
}

imagehash.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,11 @@ func (h *ImageHash) Distance(other *ImageHash) (int, error) {
4242
return -1, errors.New("Image hashes's kind should be identical")
4343
}
4444

45-
diff := 0
4645
lhash := h.GetHash()
4746
rhash := other.GetHash()
4847

4948
hamming := lhash ^ rhash
50-
for hamming != 0 {
51-
diff += int(hamming & 1)
52-
hamming >>= 1
53-
}
54-
55-
return diff, nil
49+
return popcnt(hamming), nil
5650
}
5751

5852
// GetHash method returns a 64bits hash value.

imagehash18.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// +build !go1.9
2+
3+
package goimagehash
4+
5+
func popcnt(x uint64) int {
6+
diff := 0
7+
for x != 0 {
8+
diff += int(x & 1)
9+
x >>= 1
10+
}
11+
12+
return diff
13+
}

imagehash19.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// +build go1.9
2+
3+
package goimagehash
4+
5+
import (
6+
"math/bits"
7+
)
8+
9+
func popcnt(x uint64) int { return bits.OnesCount64(x) }

0 commit comments

Comments
 (0)