Skip to content

Commit

Permalink
perf: optimize math.Int.Size for small values (#17497)
Browse files Browse the repository at this point in the history
  • Loading branch information
elias-orijtech authored Aug 22, 2023
1 parent 780cad8 commit 952328a
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
6 changes: 6 additions & 0 deletions math/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.j

# Changelog

## [Unreleased]

### Improvements

* [#17497](https://github.com/cosmos/cosmos-sdk/pull/17497) Optimize math.Int.Size for values that fit in 53 bits.

## [math/v1.1.2](https://github.com/cosmos/cosmos-sdk/releases/tag/math/v1.1.2) - 2023-08-21

### Bug Fixes
Expand Down
12 changes: 12 additions & 0 deletions math/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,15 @@ func FuzzLegacyNewDecFromStr(f *testing.F) {
}
})
}

func FuzzSmallIntSize(f *testing.F) {
f.Add(int64(2<<53 - 1))
f.Add(-int64(2<<53 - 1))
f.Fuzz(func(t *testing.T, input int64) {
i := NewInt(input)
exp, _ := i.Marshal()
if i.Size() != len(exp) {
t.Fatalf("input %d: i.Size()=%d, len(input)=%d", input, i.Size(), len(exp))
}
})
}
19 changes: 19 additions & 0 deletions math/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding"
"encoding/json"
"fmt"
stdmath "math"
"math/big"
"strings"
"sync"
Expand Down Expand Up @@ -429,6 +430,24 @@ func (i *Int) Unmarshal(data []byte) error {

// Size implements the gogo proto custom type interface.
func (i *Int) Size() int {
if i.i == nil {
return 1
}
// A float64 can store 52 bits exactly, which allows us to use
// math.Log10 to compute the size fast and garbage free.
if i.i.BitLen() <= 52 {
i64 := i.i.Int64()
if i64 == 0 {
return 1
}
size := 0
if i64 < 0 {
i64 = -i64
size++
}
return size + 1 + int(stdmath.Log10(float64(i64)))
}
// Slow path.
bz, _ := i.Marshal()
return len(bz)
}
Expand Down
12 changes: 7 additions & 5 deletions math/int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,14 +592,16 @@ func TestNewIntFromString(t *testing.T) {
}

func BenchmarkIntSize(b *testing.B) {
var tests []math.Int
for _, st := range sizeTests {
ii, _ := math.NewIntFromString(st.s)
tests = append(tests, ii)
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
for _, st := range sizeTests {
ii, _ := math.NewIntFromString(st.s)
for _, ii := range tests {
got := ii.Size()
if got != st.want {
b.Errorf("%q:: got=%d, want=%d", st.s, got, st.want)
}
sink = got
}
}
Expand Down

0 comments on commit 952328a

Please sign in to comment.