Here is my code for both contracts:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
contract StorageMapping {
struct Entity{
uint data;
address _address;
}
mapping (address => Entity) entityMapping;
function addEntity(uint _data) public {
entityMapping[msg.sender] = Entity(_data, msg.sender);
}
function updateEntity(uint _data) public {
entityMapping[msg.sender].data = _data;
}
}
contract StorageArray {
struct Entity{
uint data;
address _address;
}
Entity[] public entityArray;
function addEntity(uint _data) public {
entityArray.push(Entity(_data, msg.sender));
}
function updateEntity(uint _data) public {
for(uint i = 0; i <= entityArray.length - 1; i++) {
if(entityArray[i]._address == msg.sender) {
entityArray[i].data = _data;
}
}
}
}
Not a question but I saw someone above add this and do think it is interesting:
Array storage deploy cost: 303135 gas
Mapping storage deploy cost: 239450 gas
Array storage contract: 88190 gas
This is for the first addEntity transaction. I expect this is because it sets up the initial array where it was not before?
Second + addEntity: 71090 gas
Cost difference between first and all other times: ~21.47%
Total Cost: 372550 gas
Interestingly not that much more for the 5 addEntity calls than initial deploy.
Mapping storage contract: 66054 gas
Total cost for 5 entities: 330270 gas
No difference in first or any subsequent addEntity requests for the mapping.
The difference between the first addEntity on array and mapping:
~28.70%
The difference between the second or later calls to addEntity on array and mapping:
~7.34%
Total difference between total addEntity of both contracts:
~12.03%
When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?
The shocking result that is while if you only add 1 entity the difference is quite large (~30%), as more entries are added the less pronounced the difference between arrays and mappings become (~7%).
I would say that the difference is still significant even if you do more than the first call to addEntity. No where near as absurd as it may first appear. With a reduction beyond the first call of a little less than 4x the difference while noticeable is not as bad as the gas prices in California right now.
> Add 5 Entities into storage using the addEntity function and 5 different addresses. Then update the data of the fifth address you used. Do this for both contracts and take note of the gas consumption (execution cost). Which solution consumes more gas and why?
For the array contract updating the 5th entry costs:
43356 gas
For the mapping contract updating the 5th entry costs:
26741 gas
Total difference:
~47.40%
The array contract costs significantly more than the mapping contract. This is because of having to loop through each entry until it finds the correct one to update.
I thought that perhaps if you picked the first entry the array would be at least cheaper than updating the last entry. From my testing it is the exact same cost.
This actually makes me question if the looping is the added cost. Perhaps the array still loops through all no matter when it finds the correct one to update. Just came to me what about a break
? Going to test.
So I simply added a break;
after the update in the for loop in the array contract. Strangely even updating the 5th entry got cheaper with the break added:
42894 gas vs 43356 gas
However as expected the 1st entry was much cheaper after adding the break;
. No longer having to complete the loop through the whole array which is to be expected.
1st entry update after adding the break compared to no break:
31526 gas vs 43356 gas