Is there any reason not to use

uint[2**160-1] addressIndex;

instead of

mapping(address => uint) addressIndex;




The answer below refers to the difference between:

  • a mapping(address => uint)
  • an array of struct {address key; uint value;} elements

Which is not what's being asked here.

I'm leaving it here because I feel that it still contributes something in the context of this question...

I hope that this table answers your question:

|                | Mapping | Array |
| Add an item    | O(1)    | O(1)  |
| Remove an item | O(1)    | O(n)  |
| Find an item   | O(1)    | O(n)  |

You should choose an array over a mapping only if any of the following restrictions is given:

  1. The order of the items is important
  2. The keys of the mapping are not provided by the user
  • I think the table confusing. What does it mean "find an item" for a mapping? Maybe it is accessing an item with its key? What does it mean for an array? Maybe it is searching a value? – Ismael Jan 8 '20 at 13:57
  • @Ismael: Yeah, I'm just now realizing that what this dude has posted is an array which serves as a lookup table, which is not feasible for this range in "traditional" systems (where this range implies a huge memory consumption), but is possibly feasible on the blockchain (I guess the question is whether or not this is feasible). I was answering a different question, as I now understand, namely, why not use an array over a mapping (in which case, the array would be storing tuples of "key,value", and the complexity would be as described in my answer). This is obviously a different question. – goodvibration Jan 8 '20 at 14:13
  • @Ismael: So will probably delete this answer shortly. – goodvibration Jan 8 '20 at 14:14

They are approximately the same.

Your fixed-size array lays out a very large address space where every possible address equivalent has a slot. That's logically equivalent to what mapping does, although laid out differently (See Ismael's comment below) and slight different in gas cost as a result.

I would incline to the mapping for readability. Solidity calls for strong preference for idiomatic, readable code so there is an argument against verbosity.

There is a slight, almost insignificant gas efficiency advantage to the array with this little example (view is intentionally removed to get some gas accounting from Remix).

pragma solidity 0.5.12;

contract ArrayMapping {

    uint[2**160-1] addressIndex;
    mapping(address => uint) mapped;

    function getArray(uint row) public returns (uint) { // <== 1128 gas
        return addressIndex[row];

    function getMap(address a) public returns (uint) { // <== 1174 gas
        return mapped[a];

In case it is helpful, this tutorial lays out some ways to use arrays and mappings together. https://medium.com/robhitchens/solidity-crud-part-1-824ffa69509a

Or, you might be interested in: Are there well-solved and simple storage patterns for Solidity?

Also, your intent is clear, but it might be a good idea to be explicit about typecasting to be certain that your expression does what you think it does. IIRC there have been changes to the implicit casting, but why not be explicit?

uint(uint(2)**uint(160)-uint(1)) addressIndex;

This is to be sure you don't fall into a trap along these lines: Unexpected implicit casting in Solidity's exponential operator

Hope it helps.

  • 1
    The difference is that mapping require a keccak256(slot + key) to calculate where to read from and for an array it can be precalculated keccak256(slot) + index. – Ismael Jan 8 '20 at 18:09
  • Good point. I edited a little to capture this. Thanks. – Rob Hitchens Jan 8 '20 at 21:56

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.