一般的なハッシュ関数のパフォーマンス比較

一般的なハッシュ関数のパフォーマンス比較

結論

一般的に使われるハッシュ関数群には、処理時間に桁違いの差は見られません。ただし、これは文字列長が20000以下の範囲での結果です。

ファイルのチェックサムを求める場合は、可逆的なハッシュ関数ではなく、crcやmurmurなどの非可逆型を使用することを推奨します。

  1. crcは非常に高速ですが、murmur3と性能差はそれほどありません。標準ライブラリに含まれているため、すぐに利用できます。推奨です。
  2. md5 / shaは文字列長が短い場合でも十分な性能を示し、可逆性や散らばりの特性にこだわる必要がある場合に適しています。
  3. sha3-512crcの約8倍の処理時間を要するため、頻繁に呼び出す場合はCPU使用率が高くなる可能性があります。

ベンチマークスクリプトは末尾に記載されています。

キー長 = 20

goos: windows
goarch: amd64
pkg: hash_compare
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
BenchmarkMD5
BenchmarkMD5-19                  8822782               135.7 ns/op
BenchmarkSHA1
BenchmarkSHA1-19                 8182909               145.1 ns/op
BenchmarkSHA256
BenchmarkSHA256-19              10178547               116.2 ns/op
BenchmarkSHA512
BenchmarkSHA512-19               4528038               267.6 ns/op
BenchmarkSHA3_256
BenchmarkSHA3_256-19             2184250               556.6 ns/op
BenchmarkSHA3_512
BenchmarkSHA3_512-19             2206112               541.4 ns/op
BenchmarkCRC32
BenchmarkCRC32-19               12400216                99.20 ns/op
BenchmarkCRC64
BenchmarkCRC64-19               15547041                78.54 ns/op
BenchmarkMurmur3_32
BenchmarkMurmur3_32-19          11555438               108.0 ns/op
BenchmarkMurmur3_128
BenchmarkMurmur3_128-19          9971091               115.9 ns/op

キー長 = 50

goos: windows
goarch: amd64
pkg: hash_compare
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
BenchmarkMD5
BenchmarkMD5-19                  6289884               192.0 ns/op
BenchmarkSHA1
BenchmarkSHA1-19                 5622404               217.4 ns/op
BenchmarkSHA256
BenchmarkSHA256-19               6940231               174.1 ns/op
BenchmarkSHA512
BenchmarkSHA512-19               3849984               318.2 ns/op
BenchmarkSHA3_256
BenchmarkSHA3_256-19             2014849               593.4 ns/op
BenchmarkSHA3_512
BenchmarkSHA3_512-19             2100302               583.7 ns/op
BenchmarkCRC32
BenchmarkCRC32-19                8180628               147.6 ns/op
BenchmarkCRC64
BenchmarkCRC64-19                6771878               176.4 ns/op
BenchmarkMurmur3_32
BenchmarkMurmur3_32-19           6703288               161.6 ns/op
BenchmarkMurmur3_128
BenchmarkMurmur3_128-19          7424919               165.5 ns/op

キー長 = 100

goos: windows
goarch: amd64
pkg: hash_compare
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
BenchmarkMD5
BenchmarkMD5-19                  4070643               295.8 ns/op
BenchmarkSHA1
BenchmarkSHA1-19                 3737098               315.4 ns/op
BenchmarkSHA256
BenchmarkSHA256-19               4678782               259.2 ns/op
BenchmarkSHA512
BenchmarkSHA512-19               3292449               365.5 ns/op
BenchmarkSHA3_256
BenchmarkSHA3_256-19             1956735               619.0 ns/op
BenchmarkSHA3_512
BenchmarkSHA3_512-19             1368730               904.4 ns/op
BenchmarkCRC32
BenchmarkCRC32-19                5888480               199.0 ns/op
BenchmarkCRC64
BenchmarkCRC64-19                6796117               179.5 ns/op
BenchmarkMurmur3_32
BenchmarkMurmur3_32-19           5414822               224.4 ns/op
BenchmarkMurmur3_128
BenchmarkMurmur3_128-19          5682339               217.3 ns/op

キー長 = 1000

goos: windows
goarch: amd64
pkg: hash_compare
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
BenchmarkMD5
BenchmarkMD5-19                   534554              2200 ns/op
BenchmarkSHA1
BenchmarkSHA1-19                  623023              1999 ns/op
BenchmarkSHA256
BenchmarkSHA256-19                747392              1586 ns/op
BenchmarkSHA512
BenchmarkSHA512-19                551026              2339 ns/op
BenchmarkSHA3_256
BenchmarkSHA3_256-19              373495              3334 ns/op
BenchmarkSHA3_512
BenchmarkSHA3_512-19              254478              4723 ns/op
BenchmarkCRC32
BenchmarkCRC32-19                1000000              1187 ns/op
BenchmarkCRC64
BenchmarkCRC64-19                 959308              1367 ns/op
BenchmarkMurmur3_32
BenchmarkMurmur3_32-19            839200              1434 ns/op
BenchmarkMurmur3_128
BenchmarkMurmur3_128-19          1000000              1233 ns/op

キー長 = 10000

goos: windows
goarch: amd64
pkg: hash_compare
cpu: 12th Gen Intel(R) Core(TM) i7-12700K
BenchmarkMD5
BenchmarkMD5-19                    57900             20013 ns/op
BenchmarkSHA1
BenchmarkSHA1-19                   66994             18038 ns/op
BenchmarkSHA256
BenchmarkSHA256-19                 79039             15403 ns/op
BenchmarkSHA512
BenchmarkSHA512-19                 55267             22265 ns/op
BenchmarkSHA3_256
BenchmarkSHA3_256-19               37862             29851 ns/op
BenchmarkSHA3_512
BenchmarkSHA3_512-19               26913             52982 ns/op
BenchmarkCRC32
BenchmarkCRC32-19                  80836             15127 ns/op
BenchmarkCRC64
BenchmarkCRC64-19                  66034             17882 ns/op
BenchmarkMurmur3_32
BenchmarkMurmur3_32-19             65836             17436 ns/op
BenchmarkMurmur3_128
BenchmarkMurmur3_128-19           105553             13862 ns/op

ベンチマークスクリプト

ハッシュ関数

package hash_compare

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"hash/crc32"
	"hash/crc64"

	"github.com/twmb/murmur3"
	"golang.org/x/crypto/sha3"
)

func MD5(input string) string {
	hasher := md5.New()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func SHA1(input string) string {
	hasher := sha1.New()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func SHA256(input string) string {
	hasher := sha256.New()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func SHA512(input string) string {
	hasher := sha512.New()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func SHA3_256(input string) string {
	hasher := sha3.New256()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func SHA3_512(input string) string {
	hasher := sha3.New512()
	hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func Murmur3_32(input string) string {
	hasher := murmur3.New32()
	_, _ = hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func Murmur3_128(input string) string {
	hasher := murmur3.New128()
	_, _ = hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func CRC32(input string) string {
	hasher := crc32.New(crc32.IEEETable)
	_, _ = hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}

func CRC64(input string) string {
	hasher := crc64.New(crc64.MakeTable(crc64.ISO))
	_, _ = hasher.Write([]byte(input))
	return string(hasher.Sum(nil))
}


ベンチマークスクリプト

package hash_compare

import "testing"

var testDataLength = 10000

func generateRandomString(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	buffer := make([]byte, length)
	for i := range buffer {
		buffer[i] = charset[i%len(charset)]
	}
	return string(buffer)
}

func BenchmarkMD5(b *testing.B) {
	for i := 0; i < b.N; i++ {
		MD5(generateRandomString(testDataLength))
	}
}

func BenchmarkSHA1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SHA1(generateRandomString(testDataLength))
	}
}

func BenchmarkSHA256(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SHA256(generateRandomString(testDataLength))
	}
}

func BenchmarkSHA512(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SHA512(generateRandomString(testDataLength))
	}
}

func BenchmarkSHA3_256(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SHA3_256(generateRandomString(testDataLength))
	}
}

func BenchmarkSHA3_512(b *testing.B) {
	for i := 0; i < b.N; i++ {
		SHA3_512(generateRandomString(testDataLength))
	}
}

func BenchmarkCRC32(b *testing.B) {
	for i := 0; i < b.N; i++ {
		CRC32(generateRandomString(testDataLength))
	}
}

func BenchmarkCRC64(b *testing.B) {
	for i := 0; i < b.N; i++ {
		CRC64(generateRandomString(testDataLength))
	}
}

func BenchmarkMurmur3_32(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Murmur3_32(generateRandomString(testDataLength))
	}
}

func BenchmarkMurmur3_128(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Murmur3_128(generateRandomString(testDataLength))
	}
}


タグ: Go golang ハッシュ関数 パフォーマンス比較 CRC32

6月3日 20:54 投稿