gpt4 book ai didi

hash - Bob Jenkins 的 Hash 性能不佳

转载 作者:IT王子 更新时间:2023-10-29 00:54:29 33 4
gpt4 key购买 nike

我正在构建一个 Bloom 过滤器并查看要使用的哈希值和 Bob Jenkins' hash由于分布均匀,这似乎是一个不错的选择。我将给定的 C++ 代码改编为 Go(可能犯了一个错误,但它似乎有效)。

我着手对哈希的成本进行基准测试,发现 Go std 库中的 SHA1 哈希要快得多。

PASS
BenchmarkJenkins 1000000 2649 ns/op
BenchmarkSHA256 1000000 1218 ns/op
BenchmarkSHA1 5000000 462 ns/op

当我读到您不应在此用例中使用加密哈希时,我是否被误导了?还是标准库代码比我的优化得多?

package jenkins

import (
"bytes"
"encoding/gob"
)

// adapted from http://bretmulvey.com/hash/7.html
func ComputeHash(key interface{}) (uint64, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(key)
if err != nil {
return 0, err
}
data := buf.Bytes()

var a, b, c uint64
a, b = 0x9e3779b9, 0x9e3779b9
c = 0
i := 0

for i = 0; i < len(data)-12; {
a += uint64(data[i]) | uint64(data[i+1]<<8) | uint64(data[i+2]<<16) | uint64(data[i+3]<<24)
i += 4
b += uint64(data[i]) | uint64(data[i+1]<<8) | uint64(data[i+2]<<16) | uint64(data[i+3]<<24)
i += 4
c += uint64(data[i]) | uint64(data[i+1]<<8) | uint64(data[i+2]<<16) | uint64(data[i+3]<<24)

a, b, c = mix(a, b, c)
}

c += uint64(len(data))

if i < len(data) {
a += uint64(data[i])
i++
}
if i < len(data) {
a += uint64(data[i]) << 8
i++
}
if i < len(data) {
a += uint64(data[i]) << 16
i++
}
if i < len(data) {
a += uint64(data[i]) << 24
i++
}

if i < len(data) {
b += uint64(data[i])
i++
}
if i < len(data) {
b += uint64(data[i]) << 8
i++
}
if i < len(data) {
b += uint64(data[i]) << 16
i++
}
if i < len(data) {
b += uint64(data[i]) << 24
i++
}

if i < len(data) {
c += uint64(data[i]) << 8
i++
}
if i < len(data) {
c += uint64(data[i]) << 16
i++
}
if i < len(data) {
c += uint64(data[i]) << 24
i++
}

a, b, c = mix(a, b, c)
return c, nil
}

func mix(a, b, c uint64) (uint64, uint64, uint64) {
a -= b
a -= c
a ^= (c >> 13)
b -= c
b -= a
b ^= (a << 8)
c -= a
c -= b
c ^= (b >> 13)
a -= b
a -= c
a ^= (c >> 12)
b -= c
b -= a
b ^= (a << 16)
c -= a
c -= b
c ^= (b >> 5)
a -= b
a -= c
a ^= (c >> 3)
b -= c
b -= a
b ^= (a << 10)
c -= a
c -= b
c ^= (b >> 15)
return a, b, c
}

编辑:

基准代码:

package bloom

import (
"testing"

"crypto/sha1"
"crypto/sha256"
)

func BenchmarkJenkins(b *testing.B) {
j := jenkinsHash{}

for i := 0; i < b.N; i++ {
j.ComputeHash(i)
}
}

func BenchmarkSHA1(b *testing.B) {
for i := 0; i < b.N; i++ {
sha1.Sum([]byte{byte(i)})
}
}


func BenchmarkSHA256(b *testing.B) {
for i := 0; i < b.N; i++ {
sha256.Sum256([]byte{byte(i)})
}
}

最佳答案

我将赌注放在优化上; Bob Jenkin 的散列应该比任何加密风格的散列(如 SHA)快得多。我敢打赌,标准库为此调用了高度优化的 C(甚至汇编),这就是为什么它能击败未优化的 Go。

https://github.com/reusee/mmh3 似乎有一个有效的 Murmur3 可用于 Go (我没试过)。你可能会更幸运,或者通过调用 C/C++ 来实现你的 Bob Jenkins。

关于hash - Bob Jenkins 的 Hash 性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23436358/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com