Avoiding storage access in functions - 2
Tags: solidity, gasoptimization, bestpractice
Published: 2022-05-03 19:19:39

---series: Gas Optimization techniques---

This post is in continuation from the last one which was on saving gas by referencing data from memory. Now we will see a case where this can be contradictory.

Consider the following contracts:

```solidity
contract varReferencing_1{
    uint[] public arr;
    uint public arrLength;

    function addItem(uint _item) external {
        arrLength = arrLength + 1; // updating state

        arr.push(_item); // adding element

        for (uint i; i < arrLength; i++) {
            arr[i] = arrLength + i; // updating state
        }
    }
}


contract varReferencing_2{
    uint[] public arr;
    uint public arrLength;

    function addItem(uint _item) external {
        uint _arrLength = arrLength + 1; // storing into memory

        arr.push(_item); // adding element
        uint[] memory _arr = arr; // storing into memory

        for (uint i; i < _arrLength; i++) {
            _arr[i] = _arrLength + i;
        }

        arr = _arr; // updating state
        arrLength = _arrLength; // updating state
    }
}


contract varReferencing_3{
    uint[] public arr;
    uint public arrLength;

    function addItem(uint _item) external {
        uint _arrLength = arrLength + 1; // storing into memory

        arr.push(_item); // adding element

        for (uint i; i < _arrLength; i++) {
            arr[i] = _arrLength + i;
        }

        arrLength = _arrLength; // updating state
    }
}
```

All the three contracts have the exact same functionality, to push new element to the array and sum the index of all the elements with new array length and update it in array. (Note: this functions have no use in practical, these are just examples)

Lets see the differences and the gas spent for each contract:

**varReferencing_1**
`addItem` increases the state variable `arrLength` by 1, pushes new element `_item` to state variable array `arr` and updates each array element with new length + index.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iowovhyyyoyjfdo8p60p.PNG)

**varReferencing_2**
`addItem` increases the copy of state variable `_arrLength` by 1, pushes new element `_item` to state variable array `arr` and makes it's copy in memory. Then these copies are used to perform further operations and then assigned to original state variables.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k95wmwmn7y74yyydip60.PNG)

**varReferencing_3**
`addItem` makes copy of `arrLength` state variable in memory, but not of the `arr`. And rest of the operations are same.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3cwjqz4bp7xujz631mh.PNG)

### Conclusion
**varReferencing_2** was expected to be most gas efficient because it makes copies of both state variables, but it turned out to be most expensive. This was probably due to copying `arr` from storage to memory and then back to storage after all the operations. 
In **varReferencing_3**, we just made copy or `arrLength` and that turned out to be the most gas efficient method.