common/hexutil: improve performance of EncodeBig (#23780)

- use Text instead of fmt.Sprintf
- reduced allocs from 6 to 2
- improved speed
This commit is contained in:
lmittmann 2021-10-21 11:43:23 +02:00 committed by Daniel Liu
parent 4db72a0548
commit 49dc5e85e1
2 changed files with 18 additions and 5 deletions

View file

@ -18,7 +18,7 @@
Package hexutil implements hex encoding with 0x prefix. Package hexutil implements hex encoding with 0x prefix.
This encoding is used by the Ethereum RPC API to transport binary data in JSON payloads. This encoding is used by the Ethereum RPC API to transport binary data in JSON payloads.
Encoding Rules # Encoding Rules
All hex data must have prefix "0x". All hex data must have prefix "0x".
@ -175,13 +175,14 @@ func MustDecodeBig(input string) *big.Int {
} }
// EncodeBig encodes bigint as a hex string with 0x prefix. // EncodeBig encodes bigint as a hex string with 0x prefix.
// The sign of the integer is ignored.
func EncodeBig(bigint *big.Int) string { func EncodeBig(bigint *big.Int) string {
nbits := bigint.BitLen() if sign := bigint.Sign(); sign == 0 {
if nbits == 0 {
return "0x0" return "0x0"
} else if sign > 0 {
return "0x" + bigint.Text(16)
} else {
return "-0x" + bigint.Text(16)[1:]
} }
return fmt.Sprintf("%#x", bigint)
} }
func has0xPrefix(input string) bool { func has0xPrefix(input string) bool {

View file

@ -201,3 +201,15 @@ func TestDecodeUint64(t *testing.T) {
} }
} }
} }
func BenchmarkEncodeBig(b *testing.B) {
for _, bench := range encodeBigTests {
b.Run(bench.want, func(b *testing.B) {
b.ReportAllocs()
bigint := bench.input.(*big.Int)
for i := 0; i < b.N; i++ {
EncodeBig(bigint)
}
})
}
}