lib/protocol: Optimize luhn and chunk functions
These functions were very naive and slow. We haven't done much about them because they pretty much don't matter at all for Syncthing performance. They are however called very often in the discovery server and these optimizations have a huge effect on the CPU load on the public discovery servers. The code isn't exactly obvious, but we have good test coverage on all these functions. benchmark old ns/op new ns/op delta BenchmarkLuhnify-8 12458 1045 -91.61% BenchmarkUnluhnify-8 12598 1074 -91.47% BenchmarkChunkify-8 10792 104 -99.04% benchmark old allocs new allocs delta BenchmarkLuhnify-8 18 1 -94.44% BenchmarkUnluhnify-8 18 1 -94.44% BenchmarkChunkify-8 44 2 -95.45% benchmark old bytes new bytes delta BenchmarkLuhnify-8 1278 64 -94.99% BenchmarkUnluhnify-8 1278 64 -94.99% BenchmarkChunkify-8 42552 128 -99.70% GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4346
This commit is contained in:
committed by
Audrius Butkevicius
parent
9e6a1fdcd4
commit
9682bbfbda
21
vendor/github.com/calmh/luhn/luhn.go
generated
vendored
21
vendor/github.com/calmh/luhn/luhn.go
generated
vendored
@@ -19,10 +19,6 @@ var (
|
||||
// Generate returns a check digit for the string s, which should be composed
|
||||
// of characters from the Alphabet a.
|
||||
func (a Alphabet) Generate(s string) (rune, error) {
|
||||
if err := a.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
factor := 1
|
||||
sum := 0
|
||||
n := len(a)
|
||||
@@ -57,14 +53,15 @@ func (a Alphabet) Validate(s string) bool {
|
||||
return rune(s[len(s)-1]) == c
|
||||
}
|
||||
|
||||
// check returns an error if the given alphabet does not consist of unique characters
|
||||
func (a Alphabet) check() error {
|
||||
cm := make(map[byte]bool, len(a))
|
||||
for i := range a {
|
||||
if cm[a[i]] {
|
||||
return fmt.Errorf("Digit %q non-unique in alphabet %q", a[i], a)
|
||||
// NewAlphabet converts the given string an an Alphabet, verifying that it
|
||||
// is correct.
|
||||
func NewAlphabet(s string) (Alphabet, error) {
|
||||
cm := make(map[byte]bool, len(s))
|
||||
for i := range s {
|
||||
if cm[s[i]] {
|
||||
return "", fmt.Errorf("Digit %q non-unique in alphabet %q", s[i], s)
|
||||
}
|
||||
cm[a[i]] = true
|
||||
cm[s[i]] = true
|
||||
}
|
||||
return nil
|
||||
return Alphabet(s), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user