Improve GetValidator speed

In simulation, this was shown to cause a 4x speedup. There are no safety
concerns here, as amino encoding is deterministic.
This commit is contained in:
ValarDragon
2018-09-01 12:59:36 -07:00
parent 5643c0801b
commit a991a2e1c4
2 changed files with 27 additions and 1 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ IMPROVEMENTS
* [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check.
* [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046)
* [x/stake] [x/slashing] Ensure delegation invariants to jailed validators [#1883](https://github.com/cosmos/cosmos-sdk/issues/1883).
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
* SDK
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
* [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples.
+26
View File
@@ -2,6 +2,7 @@ package keeper
import (
"bytes"
"container/list"
"fmt"
abci "github.com/tendermint/tendermint/abci/types"
@@ -11,6 +12,14 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake/types"
)
type cachedValidator struct {
val types.Validator
marshalled string
}
var validatorCache = make(map[string]cachedValidator, 1000)
var validatorCacheList = list.New()
// get a single validator
func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator types.Validator, found bool) {
store := ctx.KVStore(k.storeKey)
@@ -18,6 +27,23 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty
if value == nil {
return validator, false
}
// return cached validator
strValue := string(value)
if val, ok := validatorCache[strValue]; ok {
valToReturn := val.val
// Doesn't mutate the cache's value
valToReturn.Operator = addr
return valToReturn, true
} else { // get validator from cache
validator = types.MustUnmarshalValidator(k.cdc, addr, value)
cachedVal := cachedValidator{validator, strValue}
validatorCache[strValue] = cachedValidator{validator, strValue}
validatorCacheList.PushBack(cachedVal)
if validatorCacheList.Len() > 500 {
valToRemove := validatorCacheList.Remove(validatorCacheList.Front()).(cachedValidator)
delete(validatorCache, valToRemove.marshalled)
}
}
validator = types.MustUnmarshalValidator(k.cdc, addr, value)
return validator, true
}