4

I am trying to find a source on what the difference is between optimized and unoptimized code. My main question is what the unoptimized compiler does, especially in the sense of calling the SSTORE opcode.

Let's say I have this:

contract A{
    uint8 mem1;
    uint8 mem2;

    function store(uint8 store1, uint8 store2){
        mem1=store1;
        mem2=store2;
    }
}

When I would compile this in a "dumb" way I would call SSTORE twice to store both variables. However, to optimize this I would allocate the first 8 bits of an uint256 (SSTORE always stores uint256's) to mem1 and the second 8 bits to mem2. Like this, I only have to call SSTORE once per transaction. However, this might result in a slight overhead in other code the contract may have since we need to extract the right bits. SSTORE takes 20k gas when saving a non-zero value, so optimizing this code saves 20k gas.

Does the unoptimized compiler, when compiling above code, call SSTORE twice or once? I know I can check this myself by compiling and reading the OPCODES, but I'd like to find a source on what both compilers should do.

  • 1
    Checking it yourself seems like the easiest option, but you could also read the compiler source code. (Search for "optimiser.") I don't think the optimizations are particularly well documented. – smarx Mar 28 '18 at 20:45
  • Allright, sad to hear that optimization is not well documented, since it is hard to learn now if you need to create "hackish" storage ways to save gas or if the optimizer does this for you. – JBrouwer Mar 28 '18 at 20:53
  • That's a very interesting question. The unoptimised compiler will generate code with 1xSLOAD and 2xSSTORE. However(!), what I was not expecting, the gas cost is still only 21000 + 26442 (geth 1.7.2). I was expecting to see something like 21000 + 200 + 40000 + X. How this can be explained? It looks like, if we write to the same address twice, the second one only costs 5000? – ivicaa Mar 30 '18 at 14:42
  • Just to be sure, you are not storing a zero the second time? 5k is gas used to store a zero. – JBrouwer Mar 30 '18 at 14:52
  • Nope. I used your code with 1,2 as parameters. – ivicaa Mar 30 '18 at 14:58
2

Does the unoptimized compiler, when compiling above code, call SSTORE twice or once?

Yes, the unoptimised code will call SSTORE twice. However, the second SSTORE to the same storage slot will only cost 5.000 gas, since it is only resetting the value in an existing slot. (See "Is the cost of updating storage different than the cost of adding to storage?")

Optimised code will only have one SSTORE.

AFAIK there is no document exactly describing what the optimiser is doing. I guess you have to go through code and ChangeLogs for this.

  • I didn't know that updating costs less. Does updating mean for 'allocated space' or for updates of sources currently in the memory? I see lots of refs to the Yellow Paper and will read it, thanks. – JBrouwer Mar 30 '18 at 18:18
  • 1
    It means: for 'allocated space'. Set -> you're creating a new node in the storage trie. Re-set -> you're changing the value of an existing trie node. Zeroing -> you're removing node(s) from the storage trie, which is rewarded with the 15.000 gas refund. – ivicaa Mar 30 '18 at 20:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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