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)
This commit is contained in:
parent
7f23d56ee5
commit
ad2b6ded3b
@ -1,3 +1,4 @@
|
|||||||
## AUTHORS
|
## AUTHORS
|
||||||
|
- [Dominik Honnef](https://github.com/dominikh) dominik@honnef.co
|
||||||
- [Dong-hee Na](https://github.com/corona10/) donghee.na92@gmail.com
|
- [Dong-hee Na](https://github.com/corona10/) donghee.na92@gmail.com
|
||||||
- [Gustavo Brunoro](https://github.com/brunoro/) git@hitnail.net
|
- [Gustavo Brunoro](https://github.com/brunoro/) git@hitnail.net
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -42,17 +42,11 @@ func (h *ImageHash) Distance(other *ImageHash) (int, error) {
|
|||||||
return -1, errors.New("Image hashes's kind should be identical")
|
return -1, errors.New("Image hashes's kind should be identical")
|
||||||
}
|
}
|
||||||
|
|
||||||
diff := 0
|
|
||||||
lhash := h.GetHash()
|
lhash := h.GetHash()
|
||||||
rhash := other.GetHash()
|
rhash := other.GetHash()
|
||||||
|
|
||||||
hamming := lhash ^ rhash
|
hamming := lhash ^ rhash
|
||||||
for hamming != 0 {
|
return popcnt(hamming), nil
|
||||||
diff += int(hamming & 1)
|
|
||||||
hamming >>= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return diff, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHash method returns a 64bits hash value.
|
// GetHash method returns a 64bits hash value.
|
||||||
|
13
imagehash18.go
Normal file
13
imagehash18.go
Normal file
@ -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
|
||||||
|
}
|
9
imagehash19.go
Normal file
9
imagehash19.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package goimagehash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/bits"
|
||||||
|
)
|
||||||
|
|
||||||
|
func popcnt(x uint64) int { return bits.OnesCount64(x) }
|
Loading…
Reference in New Issue
Block a user