Skip to content

Commit

Permalink
perf: Speedup coins.AmountOf() by removing many regex calls (backport c…
Browse files Browse the repository at this point in the history
…osmos#10021) (cosmos#10166)

* perf: Speedup coins.AmountOf() by removing many regex calls (cosmos#10021)

(cherry picked from commit ed35bfd)

# Conflicts:
#	CHANGELOG.md

* fix conflict

* fix changelog

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
  • Loading branch information
3 people authored and JeancarloBarrios committed Sep 28, 2024
1 parent c44be9e commit 4d04367
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 14 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### Improvements
* (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls.

### Bug Fixes

* (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly.
Expand Down
18 changes: 4 additions & 14 deletions types/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,18 +701,7 @@ func (coins Coins) AmountOf(denom string) math.Int {

// AmountOfNoDenomValidation returns the amount of a denom from coins
// without validating the denomination.
// CONTRACT: coins must be valid (sorted).
func (coins Coins) AmountOfNoDenomValidation(denom string) math.Int {
if ok, c := coins.Find(denom); ok {
return c.Amount
}
return math.ZeroInt()
}

// Find returns true and coin if the denom exists in coins. Otherwise it returns false
// and a zero coin. Uses binary search.
// CONTRACT: coins must be valid (sorted).
func (coins Coins) Find(denom string) (bool, Coin) {
func (coins Coins) AmountOfNoDenomValidation(denom string) Int {
switch len(coins) {
case 0:
return false, Coin{}
Expand All @@ -725,15 +714,16 @@ func (coins Coins) Find(denom string) (bool, Coin) {
return false, Coin{}

default:
// Binary search the amount of coins remaining
midIdx := len(coins) / 2 // 2:1, 3:1, 4:2
coin := coins[midIdx]
switch {
case denom < coin.Denom:
return coins[:midIdx].Find(denom)
return coins[:midIdx].AmountOfNoDenomValidation(denom)
case denom == coin.Denom:
return true, coin
default:
return coins[midIdx+1:].Find(denom)
return coins[midIdx+1:].AmountOfNoDenomValidation(denom)
}
}
}
Expand Down

0 comments on commit 4d04367

Please sign in to comment.