4
pragma solidity 0.4.24;

contract Test {

    struct Book {
        uint id;
    }

    Book[] books;

    uint public status;

    constructor() public {
        books.push(Book(10));
    }

    function changeStatus1() external {
        Book storage book = books[0];
        if (book.id == 10) {
            status = 1;
        }
    }

    function changeStatus2() external {
        Book memory book = books[0];
        if (book.id == 10) {
            status = 2;
        }
    }
}

It seems like the method that uses storage costs less gas (26982 vs 27063). What is the best practice when just reading the value (and maybe using it in an if statement). Should I use storage or memory?

1

3 Answers 3

5

Your first function creates a memory pointer to a location in storage and works with it.

Your second function creates a memory variable and copies data to it from storage.

Here's a third way that doesn't use memory and costs a little less.

function changeStatus3() external {
    if (books[0].id == 2) { 
        status = 3;
    }
}

Hope it helps.

2
  • 1
    Would a memory pointer always be cheaper than a memory variable in terms of gas costs? Commented Aug 3, 2018 at 17:38
  • 3
    I don't think one can generalize like that and always be right. For example, if the process is slightly more involved and accesses the value more than once, then the advantage goes to read it from storage once and store a copy in memory. Commented Aug 3, 2018 at 18:06
2

This can be a confusing subject.

In your first function, changeStatus1(), the storage keyword is essentially allowing the book variable to act as a pointer into the storage array, books[]. You are not declaring a new variable in storage, which cannot be done inside a function.

This would be the correct option to use.


In your second function, the memory keyword is allocating memory for a new variable that is scoped to that function. The memory will be cleaned up once the function has executed, however it is possible to push the contents of that memory into storage before the function returns.

-1

1) storage variables are the ones which define your contract’s state and are only changed by sendTransaction calls

2) memory variables are temporary variables that exist only inside the calling function (they cannot be declared outside of one). They get wiped after the function exits and they are generally cheaper to use than storage variables.

Ideally, the method that uses memory variable should cost less gas as compare to a method that uses storage variable. Logically you should use memory variable. For more details refer to this article.

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.