mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 23:25:22 +00:00
state: optimize NEP17Balance
deserialization
``` BenchmarkNEP17BalanceFromBytes/stackitem-8 2402318 503.3 ns/op 208 B/op 10 allocs/op BenchmarkNEP17BalanceFromBytes/from_bytes-8 7623139 160.7 ns/op 72 B/op 3 allocs/op ``` Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
3218b74ea5
commit
b210a34b1e
2 changed files with 63 additions and 5 deletions
|
@ -25,12 +25,25 @@ type NEOBalance struct {
|
||||||
|
|
||||||
// NEP17BalanceFromBytes converts serialized NEP17Balance to structure.
|
// NEP17BalanceFromBytes converts serialized NEP17Balance to structure.
|
||||||
func NEP17BalanceFromBytes(b []byte) (*NEP17Balance, error) {
|
func NEP17BalanceFromBytes(b []byte) (*NEP17Balance, error) {
|
||||||
balance := new(NEP17Balance)
|
if len(b) < 4 {
|
||||||
err := balanceFromBytes(b, balance)
|
if len(b) == 0 {
|
||||||
if err != nil {
|
return new(NEP17Balance), nil
|
||||||
return nil, err
|
}
|
||||||
|
return nil, errors.New("invalid format")
|
||||||
}
|
}
|
||||||
return balance, nil
|
if b[0] != byte(stackitem.StructT) {
|
||||||
|
return nil, errors.New("not a struct")
|
||||||
|
}
|
||||||
|
if b[1] != 1 {
|
||||||
|
return nil, errors.New("invalid item count")
|
||||||
|
}
|
||||||
|
if st := stackitem.Type(b[2]); st != stackitem.IntegerT {
|
||||||
|
return nil, fmt.Errorf("invalid balance: %s", st)
|
||||||
|
}
|
||||||
|
if int(b[3]) != len(b[4:]) {
|
||||||
|
return nil, errors.New("invalid balance format")
|
||||||
|
}
|
||||||
|
return &NEP17Balance{Balance: *bigint.FromBytes(b[4:])}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns serialized NEP17Balance.
|
// Bytes returns serialized NEP17Balance.
|
||||||
|
|
|
@ -20,6 +20,31 @@ func TestNEP17Balance_Bytes(t *testing.T) {
|
||||||
ret := b.Bytes(buf[:0])
|
ret := b.Bytes(buf[:0])
|
||||||
require.Equal(t, ret, buf[:len(ret)])
|
require.Equal(t, ret, buf[:len(ret)])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
actual, err := NEP17BalanceFromBytes(data)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, &b, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNEP17BalanceFromBytesInvalid(t *testing.T) {
|
||||||
|
b, err := NEP17BalanceFromBytes(nil) // 0 is ok
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), b.Balance.Int64())
|
||||||
|
|
||||||
|
_, err = NEP17BalanceFromBytes([]byte{byte(stackitem.StructT)})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = NEP17BalanceFromBytes([]byte{byte(stackitem.IntegerT), 4, 0, 1, 2, 3})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = NEP17BalanceFromBytes([]byte{byte(stackitem.StructT), 0, byte(stackitem.IntegerT), 1, 1})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = NEP17BalanceFromBytes([]byte{byte(stackitem.StructT), 1, byte(stackitem.ByteArrayT), 1, 1})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = NEP17BalanceFromBytes([]byte{byte(stackitem.StructT), 1, byte(stackitem.IntegerT), 2, 1})
|
||||||
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkNEP17BalanceBytes(b *testing.B) {
|
func BenchmarkNEP17BalanceBytes(b *testing.B) {
|
||||||
|
@ -48,3 +73,23 @@ func BenchmarkNEP17BalanceBytes(b *testing.B) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkNEP17BalanceFromBytes(b *testing.B) {
|
||||||
|
var bl NEP17Balance
|
||||||
|
bl.Balance.SetInt64(0x12345678910)
|
||||||
|
|
||||||
|
buf := bl.Bytes(nil)
|
||||||
|
|
||||||
|
b.Run("stackitem", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = stackitem.DeserializeConvertible(buf, new(NEP17Balance))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("from bytes", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, _ = NEP17BalanceFromBytes(buf)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue