50
contract A {
  uint8 a = 0;
}

costs 20150 + 2000 gas during creation.

as compared to

contract A {
  uint a = 0;   // or uint256
}

costing 5050 + 2000 gas during creation

It is odd that a variable that's taking less storage space is costing more gas. Why is that so?

0
62

The EVM works with 256bit/32byte words (debatable design decision). Every operation is based on these base units. If your data is smaller, further operations are needed to downscale from 256 bits to 8 bits, hence why you see increased costs.

Btw, if you toggle the "Details" on the online solidity compiler, it will give you the exact assembly dump where the extra opcodes are from. I didn't have time now to interpret them, but if you do and find there's something extra, I'm sure the Solidity team would be happy to add optimizations to work around them.

3
  • Yeah I saw the assembly instructions. I was going to examine it further if I couldn't get any answers here. Thanks for your reply. It's an odd decision to start with uint256. Next question I wonder if it's then always make sense to just stick to uint256 and never smaller.
    – uzyn
    Apr 16 '16 at 14:53
  • 8
    @uzyn Using smaller values for storage makes sense, because writing to storage is expensive, and the compiler will pack multiple smaller arguments. For function parameters and memory variables, it only makes sense if you want to restrict the range of values: there's no packing, so it's neither more nor less expensive. Apr 16 '16 at 15:22
  • 6
    When we create a variable as uint32 inside a struct instead of uint256 and push it into an array it cost much less gas tho.
    – alper
    Feb 2 '17 at 10:03
33

It should be noted however, that in a struct, uint8 DOES cost less than a traditional uint, because of the tight packing feature. Also be sure that your uints are next to your other uints, and bytes next to bytes, etc...this further increases the tightly packed features.

2
  • 1
    What do you mean by "be sure that your uints are next to your other uints, and bytes next to bytes, etc...". So in a struct should uints should be defined one after each other on other types as well and why? @VoR0220
    – alper
    Aug 28 '18 at 12:26
  • 2
    He recommends this because the order you declare your state variables can affect the overall number of storage slots your contract uses. If you declare 2 uint128's and then a uin256, that will use 2 256-bit storage slots; 1 slot for the 2 uint128's and 1 slot for the uint256. If you declare 1 uint128, then a uint256, then a uint128, your contract will use 3 storage slots, because it can't fit the middle uint256 state variable into a storage slot with either of the uint128's, so each variable will need to have its own storage slot.
    – almel
    Apr 25 at 16:43
13

SOLC 0.4.18: now the difference is small

https://ethfiddle.com/6lt852gx7K

Contract A using uint8 costs 75414 to deploy

Contract B using uint256 costs 73867 to deploy

A difference of 1547 gas.

1
  • 1
    still true in newest solidity versions (same exact costs for 0.6.11 and 0.7.1) Jan 22 at 19:13

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.