0

Say I have a complex(list, mapping or struct) global/contract variable. What is the most gas efficient way to update that variable in a function that changes the value of one or more indexes, values or members in the case of the variable being a list, mapping or struct respectively.

The first option I can think of would be to directly write the value/s to state, but I think this would be the most gas intensive as for every direct update you have one read and one write operation.

The second option would be to read that variable into a local state variable, perform updates on that local variable, then assign the global variable to that local variable. This initially seems to be more gas efficient than option 1, but this would only be true if the gas cost of assignment is fixed, for example if the contract variable is a list then gas cost to write the local list to the contract list is fixed regardless of the length, so the gas cost of assigning a local list to a contract list of length 1 is equal to the gas cost if the list was of length 1000, and similarly for other complex types i.e. mapping and struct.

1 Answer 1

0

I've tested the following list example in Remix and it appears that option 2 is more gas expensive as it reassigns every element in the global list, not just the changed values. I'd assume the same issue would exist for mapping making option 2 the better option for list and mapping, but for struct variables(assuming the struct is composed of simple members i.e. no mapping or list members) option 2 would be more gas efficient as per my previous test

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract ComplexType {

    uint[100] public numbers;

    struct Number {
        uint number;
        uint index;
    }
    
    // option 1: direct update to indexes in state
    function push1(Number[] memory indexesToChange) external {

        for (uint i=0; i < indexesToChange.length; i++) {
            numbers[indexesToChange[i].index] += indexesToChange[i].number;
        }
    }

    // option 2: read state into local, update local then write local to state
    function push2(Number[] memory indexesToChange) external {

        uint[100] memory _numbers = numbers;

        for (uint i=0; i < indexesToChange.length; i++) {
            _numbers[indexesToChange[i].index] += indexesToChange[i].number;
        }

        numbers = _numbers;
    }    
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.