solidity – What is the Most Gas Efficient Way to Initialize a Struct in Solidity?

local-variablessoliditystruct

Say I define a struct named MyStruct and a local variable called myStruct, what is the most gas efficient way to assign/update 1 or more fields/members of myStruct? If I wanted to assign a new value to all fields, I'd imagine assigning myStruct to a new MyStruct would be more efficient than individually assigning all fields in myStruct, but what if I wanted to update only a select number of fields in myStruct leaving all other fields unchanged?

Assigning new values to all fields in myStruct:

struct MyStruct {
  bool isTrue;
  uint16 twoBytes;
}

// option 1:
myStruct = MyStruct(true, 100);

// option 2:
myStruct.isTrue = true;
myStruct.twoBytes = 100;

// My guess is option 1 is better option 2

Updating selected fields in myStruct leaving all else equal:

// option 1:
myStruct = MyStruct(myStruct.isTrue, 100);

// option 2:
myStruct.twoBytes = 100;

// not sure which is the better option; and whether it may be dependent on the struct schema

Best Answer

So I ran all 4 scenarios in remix as this is what I found, when assigning new values to all fields in myStruct option 1 is indeed cheaper than option 2, and when updating selected fields in myStruct leaving all else equal option 2 is cheaper than option 1.

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

contract Structs {

    struct MyStruct {
        bool isTrue;
        uint16 twoBytes;
    }

    MyStruct myStruct;

    constructor() {
        myStruct = MyStruct(true, 10);
    }

    // Execution cost: 23694
    function assignAllViaStruct() external view {

        MyStruct memory _myStruct = myStruct;
        _myStruct = MyStruct(true, 100);
    }

    // Execution cost: 23773
    function assignAllViaFields() external view {
        MyStruct memory _myStruct = myStruct;
        _myStruct.isTrue = true;
        _myStruct.twoBytes = 100;
    }

    // Execution cost: 23725
    function assignSelectViaStruct() external view {
        MyStruct memory _myStruct = myStruct;
        _myStruct = MyStruct(_myStruct.isTrue, 100);
    }

    // Execution cost: 23708
    function assignSelectViaFields() external view {
        MyStruct memory _myStruct = myStruct;
        _myStruct.twoBytes = 100;
    }    
}
Related Topic