x/evm/keeper: use the fastest slice making idiom for Keeper.EthereumTx.Logs (#827)

Uses the fastest slice making idiom of creating the well known
size of a slice using

    make([]sdk.Attribute, len(response.Logs))
    for i, log := range response.Logs {
        txLogAttrs[i] = ...
    }

instead of

    make([]sdk.Attribute, 0)
    for _, log := range response.Logs {
        txLogAttrs = append(txLogAttrs, ...)
    }

which had a few problems:
1. Using 0 for size then appending is quite slow yet we know the exact size
2. Using append instead of indexing is slower

If we examine the advisory at https://bencher.orijtech.com/perfclinic/sliceupdate/
and the verdict at https://bencher.orijtech.com/perfclinic/sliceupdate/#verdict
this new scheme shows a massive improvement in that call site.

Fixes #825
This commit is contained in:
Emmanuel T Odeke 2021-12-13 16:05:12 -08:00 committed by GitHub
parent 4ee1d86377
commit a2f246c2a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 3 deletions

View File

@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements ### Improvements
* (evm) [tharsis#826](https://github.com/tharsis/ethermint/issues/826) Improve allocation of bytes of `tx.To` address. * (evm) [tharsis#826](https://github.com/tharsis/ethermint/issues/826) Improve allocation of bytes of `tx.To` address.
* (evm) [tharsis#827](https://github.com/tharsis/ethermint/issues/827) Speed up creation of event logs by using the slice insertion idiom with indices.
### Bug Fixes ### Bug Fixes

View File

@ -52,13 +52,13 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyEthereumTxFailed, response.VmError)) attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyEthereumTxFailed, response.VmError))
} }
txLogAttrs := make([]sdk.Attribute, 0) txLogAttrs := make([]sdk.Attribute, len(response.Logs))
for _, log := range response.Logs { for i, log := range response.Logs {
value, err := json.Marshal(log) value, err := json.Marshal(log)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(err, "failed to encode log") return nil, sdkerrors.Wrap(err, "failed to encode log")
} }
txLogAttrs = append(txLogAttrs, sdk.NewAttribute(types.AttributeKeyTxLog, string(value))) txLogAttrs[i] = sdk.NewAttribute(types.AttributeKeyTxLog, string(value))
} }
// emit events // emit events