perf(constants): avoid allocating a map for each Decode*() call
```
goos: linux
goarch: amd64
pkg: github.com/ucan-wg/go-varsig
cpu: 13th Gen Intel(R) Core(TM) i7-1360P
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
DecodeHashAlgorithm-16 145.65n ± 10% 59.62n ± 30% -59.07% (p=0.000 n=10)
DecodePayloadEncoding-16 136.65n ± 46% 50.02n ± 5% -63.40% (p=0.000 n=10)
geomean 141.1n 54.60n -61.29%
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
DecodeHashAlgorithm-16 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) ¹
DecodePayloadEncoding-16 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) ¹
geomean 48.00 48.00 +0.00%
¹ all samples are equal
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
DecodeHashAlgorithm-16 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
DecodePayloadEncoding-16 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
geomean 1.000 1.000 +0.00%
¹ all samples are equal
```
This commit is contained in:
51
constant.go
51
constant.go
@@ -12,7 +12,7 @@ import (
|
|||||||
const Prefix = uint64(multicodec.Varsig)
|
const Prefix = uint64(multicodec.Varsig)
|
||||||
|
|
||||||
// HashAlgorithm is the multicodec.Code that specifies the hash algorithm
|
// HashAlgorithm is the multicodec.Code that specifies the hash algorithm
|
||||||
// that's used to reduced the signed content
|
// that's used to reduce the signed content
|
||||||
type HashAlgorithm uint64
|
type HashAlgorithm uint64
|
||||||
|
|
||||||
// Constant multicodec.Code values that allow Varsig implementations to
|
// Constant multicodec.Code values that allow Varsig implementations to
|
||||||
@@ -36,16 +36,15 @@ func DecodeHashAlgorithm(r *bytes.Reader) (HashAlgorithm, error) {
|
|||||||
|
|
||||||
h := HashAlgorithm(u)
|
h := HashAlgorithm(u)
|
||||||
|
|
||||||
if _, ok := map[HashAlgorithm]struct{}{
|
switch h {
|
||||||
HashAlgorithmSHA256: {},
|
case HashAlgorithmSHA256,
|
||||||
HashAlgorithmSHA384: {},
|
HashAlgorithmSHA384,
|
||||||
HashAlgorithmSHA512: {},
|
HashAlgorithmSHA512,
|
||||||
HashAlgorithmShake256: {},
|
HashAlgorithmShake256:
|
||||||
}[h]; !ok {
|
return h, nil
|
||||||
|
default:
|
||||||
return HashAlgorithmUnspecified, fmt.Errorf("%w: %x", ErrUnknownHashAlgorithm, h)
|
return HashAlgorithmUnspecified, fmt.Errorf("%w: %x", ErrUnknownHashAlgorithm, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
return h, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PayloadEncoding specifies the encoding of the data being (hashed and)
|
// PayloadEncoding specifies the encoding of the data being (hashed and)
|
||||||
@@ -88,32 +87,30 @@ func DecodePayloadEncoding(r *bytes.Reader, vers Version) (PayloadEncoding, erro
|
|||||||
|
|
||||||
// https://github.com/ChainAgnostic/varsig#4-payload-encoding
|
// https://github.com/ChainAgnostic/varsig#4-payload-encoding
|
||||||
func decodeEncodingInfoV0(payEnc PayloadEncoding) (PayloadEncoding, error) {
|
func decodeEncodingInfoV0(payEnc PayloadEncoding) (PayloadEncoding, error) {
|
||||||
if _, ok := map[PayloadEncoding]struct{}{
|
switch payEnc {
|
||||||
PayloadEncodingVerbatim: {},
|
case PayloadEncodingVerbatim,
|
||||||
PayloadEncodingDAGPB: {},
|
PayloadEncodingDAGPB,
|
||||||
PayloadEncodingDAGCBOR: {},
|
PayloadEncodingDAGCBOR,
|
||||||
PayloadEncodingDAGJSON: {},
|
PayloadEncodingDAGJSON,
|
||||||
PayloadEncodingJWT: {},
|
PayloadEncodingJWT,
|
||||||
PayloadEncodingEIP191: {},
|
PayloadEncodingEIP191:
|
||||||
}[payEnc]; !ok {
|
return payEnc, nil
|
||||||
|
default:
|
||||||
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version0, payEnc)
|
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version0, payEnc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return payEnc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/expede/varsig/blob/main/README.md#payload-encoding
|
// https://github.com/expede/varsig/blob/main/README.md#payload-encoding
|
||||||
func decodeEncodingInfoV1(payEnc PayloadEncoding) (PayloadEncoding, error) {
|
func decodeEncodingInfoV1(payEnc PayloadEncoding) (PayloadEncoding, error) {
|
||||||
if _, ok := map[PayloadEncoding]struct{}{
|
switch payEnc {
|
||||||
PayloadEncodingVerbatim: {},
|
case PayloadEncodingVerbatim,
|
||||||
PayloadEncodingDAGCBOR: {},
|
PayloadEncodingDAGCBOR,
|
||||||
PayloadEncodingDAGJSON: {},
|
PayloadEncodingDAGJSON,
|
||||||
PayloadEncodingEIP191: {},
|
PayloadEncodingEIP191:
|
||||||
}[payEnc]; !ok {
|
return payEnc, nil
|
||||||
|
default:
|
||||||
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version1, payEnc)
|
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version1, payEnc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return payEnc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discriminator is (usually) the multicodec.Code representing the public
|
// Discriminator is (usually) the multicodec.Code representing the public
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ func TestDecodeHashAlgorithm(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkDecodeHashAlgorithm(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
data := []byte{0x12}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, _ = varsig.DecodeHashAlgorithm(bytes.NewReader(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDecodePayloadEncoding(t *testing.T) {
|
func TestDecodePayloadEncoding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -105,3 +113,11 @@ func TestDecodePayloadEncoding(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkDecodePayloadEncoding(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
data := []byte{0x5f}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, _ = varsig.DecodePayloadEncoding(bytes.NewReader(data), varsig.Version1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user