diff --git a/CHANGELOG.md b/CHANGELOG.md index cfe08c13ccf6..50ae73502d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,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. diff --git a/types/coin.go b/types/coin.go index 3cfc58b7b3bb..e8fe7a5f8781 100644 --- a/types/coin.go +++ b/types/coin.go @@ -517,7 +517,12 @@ func (coins Coins) Empty() bool { // AmountOf returns the amount of a denom from coins func (coins Coins) AmountOf(denom string) Int { mustValidateDenom(denom) + return coins.AmountOfNoDenomValidation(denom) +} +// AmountOfNoDenomValidation returns the amount of a denom from coins +// without validating the denomination. +func (coins Coins) AmountOfNoDenomValidation(denom string) Int { switch len(coins) { case 0: return ZeroInt() @@ -530,15 +535,16 @@ func (coins Coins) AmountOf(denom string) Int { return ZeroInt() 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].AmountOf(denom) + return coins[:midIdx].AmountOfNoDenomValidation(denom) case denom == coin.Denom: return coin.Amount default: - return coins[midIdx+1:].AmountOf(denom) + return coins[midIdx+1:].AmountOfNoDenomValidation(denom) } } }