Assignment - Storage Design

Array:

  • Deployment cost: 306987 gas
  • Add entity cost: 71212 (first cost 88312) gas
  • Update entity: 42268 gas

Map:

  • Deployment cost: 231440
  • Add entity cost: 43797 gas
  • Update entity: 26943 gas

The mapping is significantly cheaper in all respects. This is due to the array connecting all the structs together (iterability has a price) making it far more expensive. It should also be noted that addEntity command is far more expensive for arrays. Probably due to having to tie the new struct up with the others or if it works like other languages then the array size is actually immutable and it has to create a new array to which it copies the old data from before adding the new data.
As for updating the data, the main reason is probably due to the need of traversing the array making an update cost in accordance with O(n) or rather the length of the array in opposition of maps which are O(1), constant.

Am I correct?

1 Like

Mapping

//SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

contract MappingExample{

    struct Entity{
    uint data;
    address _address;
    }

    mapping(address => Entity) Entitymapping;

    function addEntity(uint _data) public {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = msg.sender;
        Entitymapping[msg.sender] = newEntity;
    }

    function updateEntity(address _user, uint data) public returns(uint)
    {
        Entitymapping[_user].data = data;
        return(2);
    }
}

Array

//SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

contract ArrayExample{

    struct Entity{
    uint data;
    address _address;
    }

    Entity[] EntityArray;

    function AddPerson(uint _data) public returns(uint)
    {
        Entity memory newPerson;
        newPerson.data = _data;
        newPerson._address = msg.sender;
        EntityArray.push(newPerson);
        return(2);
    }

    function changeData(uint _index, uint newData) public returns(uint)
    {
        EntityArray[_index].data = newData;
        return(1);
    }
}

Questions:
When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?
addEntity cost for Array 71405
addEntity cost for Mapping 66176
The mapping is cheaper since the array uses an iterative strategy which of course will require more gas.
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?
Mapping 27484
Array 29308
The array is more expensive since like previously mentioned it needs to iterate through the data stored to find the user while the mapping uses a key-value strategy.

1 Like

When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?

The array solution uses a bit more gas than the the mapping.

Mapping Cost
Initial Transaction 66260 gas
Subsequent Transactions 66260 gas

Array Cost
Initial transaction 88389 gas
Subsequent transactions 71289 gas

I was a bit surprised the costs for the array weren’t higher, but I have a rather simple function for adding new values to the array so it may save on some cost.

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?

The array solution costs more to update due to the update function needing to go through the array to find the correct position to update.

Mapping Cost
Initial Transaction 66260 gas
Subsequent Transactions 66260 gas
Update 26921 gas

Array Cost
Initial transaction 88389 gas
Subsequent transactions 71289 gas
Update 41719 gas

Using a mapping

pragma solidity 0.8.0;

//SPDX-License-Identifier: UNLICENSED


contract withoutArray{

    struct Entity{
    uint data;
    address _address;
    }

    mapping(address => Entity) public entityStruct;

    function addEntity(uint _data) public returns(bool success){
        entityStruct[msg.sender].data = _data;
        entityStruct[msg.sender]._address = msg.sender;
        return true;
    }

    function updateEntity(uint _data) public returns(bool success){
        entityStruct[msg.sender].data = _data;
        return true;
    }


}

Using an Array

pragma solidity 0.8.0;

//SPDX-License-Identifier: UNLICENSED


contract withArray{

    struct Entity{
    uint data;
    address _address;
    }
  
  Entity[] entities;

  function addEntity(uint _data) public returns(bool success){
      //add new entity to entities array
      entities.push(Entity(_data,msg.sender));
      return true;
       }

    function updateEntity(uint _data) public{   
        //loop through array 
        for(uint i = 0; i < entities.length; i++){
            //if entities._address is equal to msg.sender, update entities.data
            if(entities[i]._address == msg.sender){
                entities[i].data = _data;  
            }
        }
    }

}
1 Like

Array--------- addEntity -----> Gas = 88936
updateEntity-----> Gas = 32025
updateEntity 5th address-----> Gas = 53489

                         COMPIRED TO

Mapping---------addEntity------> Gas = 66682
updateEntity ------> Gas = 27118
updateEntity 5th address-----> Gas = 27118

From every indication Array consumed more Gas than Mapping, due to it storage condition which need iteration using Loop to search for data.

2 Likes

onlyArray.sol

pragma solidity 0.8.0;

contract OnlyArray {

    struct Entity{

        uint data;

        address _address;

    }

    Entity[] public entityStructs;

    function addEntity(uint _data) public {

        Entity memory newEntity;

        newEntity.data = _data;

        newEntity._address = msg.sender;

        entityStructs.push(newEntity);

    }

    function updateEntity(uint _data) public {

        for (uint i=0; i<entityStructs.length; i++){

            if (entityStructs[i]._address == msg.sender){

                entityStructs[i].data = _data;

                break;

            }

        }

       

    }

}

onlyMapping.sol

pragma solidity 0.8.0;

contract OnlyMapping {

    struct Entity {

        uint data;

        address _address;

    }

    mapping (address => Entity) public entityStructs;

    function addEntity(uint _data) public{

        require(entityStructs[msg.sender].data == 0);

        entityStructs[msg.sender].data = _data;

    }

    function updateEntity(uint _data) public{

        entityStructs[msg.sender].data = _data;

    }

}

addEntity():

onlyArray.sol: 88312 gas
onlyMapping.sol: 43915 gas

When executing the addEntity function, the array contract consumed more gas (88312 gas) than the mapping contract (43915 gas).

This is a significant difference because twice as much gas was used by the array contract.

updateEntity():

onlyArray.sol: 41991 gas
onlyMapping.sol: 26741 gas

The array solution consumes more gas when updating entities because it has to loop through each entity in the array to find the correct one. However, the mapping only has to do a simple lookup.

Storage with only Array:

contract StorageWithArray {

   struct Entity{
        uint data;
        address _address;
    }

    Entity[] entityLog;

    function addEntity(uint _data) public {
        Entity memory newEntity = Entity(_data, msg.sender);
        entityLog.push(newEntity);
    }

    function updateEntity(uint _data) public {
        
        for (uint i=0; i<entityLog.length; i++){
            if (entityLog[i]._address == msg.sender){
                entityLog[i].data = _data;
            }
        }

    }

}

Storage with only mapping:

contract StorageWithMapping {
    struct Entity{
        uint data;
        address _address;
    }

    mapping(address => Entity) entity;


    function addEntity(uint _data) public {
   
        entity[msg.sender].data = _data;
       // entity[msg.sender].isEntity = true;
    }

    function updateEntity(uint _data) public {
   
        entity[msg.sender].data = _data;
    }
}

From deploying the two contracts above, the following gas cost data was gotten.

Gas for storage with array

Adding New Entry:
execution cost : 88111 gas

Update Entry:
execution cost: 31317 gas

/////////////////////////////////////////

Gas for storage with only mapping

Adding New Entry:
execution cost : 43619 gas

Updating Entry:
execution cost: 26541 gas

1 Like
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;

contract mappingEntity{
    struct Entity{
        uint entityData;
        address entityAddress;
    }
    

    mapping(address =>Entity) public Entities;

    function addEntity(uint _entityData) public {
        Entities[msg.sender].entityData=_entityData;
        
        Entities[msg.sender].entityAddress=msg.sender;
       
    }

    function updateEntity(uint _entityData) public{
        Entities[msg.sender].entityData=_entityData;

    }


}


// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;

contract arrayEntity{

    struct Entity{
        uint entityData;
        address entityAddress;
    }

    Entity[] public entities;

    function addEntity(uint _entityData) public{
        entities.push(Entity(_entityData,msg.sender));

    }

    function updateEntity(uint _entityData) public {
        for(uint i=0;i<entities.length;i++){
            if(entities[i].entityAddress==msg.sender){
                entities[i].entityData=_entityData;
                break;


            }

        }
    }
}

Above our my two contracts for array and mapping storage.
ARRAY Storage
1. First entry on array, cost was 88190 gas.
2 After first entry 2,3,4,5 entry, cost was 71090 gas.
3. Update of 5th entry, cost was 41991 gas.
MAPPING storage
1. First entry on mapping, cost was 66058 gas.
2. for 2,3,4,5 entry , cost was same 66058 gas.
3. Update cost of 5th entry, cost was 26719 gas.
In array initialization cost is more and after that in adding entity cost of gas was not much different than mapping.
But updation cost on array cost considerably 35% more than mapping.

2 Likes

The code:


pragma solidity 0.7.5;

contract EntityMapping{

struct Entity{
uint _data;
address _address;
}
mapping(address => Entity) entities;

function addEntity(uint data) public {

entities[msg.sender]._data =data;

}

function updateEntity(uint data)public{
entities[msg.sender]._data=data;

}

}

Array Version: 
pragma solidity 0.7.5;



contract EntityArray{

struct Entity{
    uint _data;
    address _address;
}

Entity[] entities;


function addEntity(uint data) public {
    Entity memory newEntity;
    newEntity._data =data;
    newEntity._address=msg.sender;
    entities.push(newEntity);
}

function updateEntity(uint data)public {

    for (uint i=0; i<entities.length; i++){
        if (entities[i]._address==msg.sender){
            entities[i]._data=data;
          
        }
    }
  

}
}

The Mapping solution is more GAs efficient in every transaction, Deployment, Adding and updating, and also it is constant for each update, add transaction. in Arrays the update increase each higher position.
I understand that the code is lighter in the mapping version and it is more efficient for updates, but I can not understand why adding is a lot costly in the Array than in the mapping. 81112 gas for the 1st element and 71K in the array vs a constant 43619 gas in Mapping. push() an element at the end of the array should be a very easy and cheap operation. someone can help?

To add new entity:
Mapping - 66,627 gas per transaction
Array - 88,896 gas for first transaction, 71,796 gas for all subsequent transactions
Using the array method costs about 13% more in gas across 5 transactions.

Update entity:
Mapping - 29,237 gas per transaction
Array - 31,737 gas per transaction
Using array method costs about 9% more in gas.

Mapping solution code

`pragma solidity 0.8.0;

contract storageDesignMapping {

struct Entity{
    uint data;
    address _address;
    bool isEntity;
}

mapping(address => Entity) entityMapping;

function addEntity(uint _data) public returns (bool success) {
    require(entityMapping[msg.sender].isEntity == false, "Entity already exists");
    entityMapping[msg.sender].data = _data;
    entityMapping[msg.sender].isEntity = true;
    return true;

}

function updateEntity(uint _data) public returns (bool success) {
    require(entityMapping[msg.sender].isEntity == true, "Entity does not exist");
    entityMapping[msg.sender].data = _data;
    return true;

}

}`

Array solution code

`pragma solidity 0.8.0;

contract storageDesignArray {

struct Entity{
    uint data;
    address _address;
}

Entity[] public entityArray;

function addEntity(uint _data) public returns (bool success, uint newIndex) {
    Entity memory newEntity;
    newEntity.data = _data;
    newEntity._address = msg.sender;
    entityArray.push(newEntity);
    return (true, entityArray.length-1);
    }

function updateEntity(uint _index, uint _data) public returns (bool success) {
    require(entityArray[_index]._address == msg.sender, "Incorrect index or entity does not exist");
    entityArray[_index].data = _data;
    return true;

}

}`

1 Like

Code:

Mapping
pragma solidity 0.8.0;

contract MappingStorageAssignment {

   struct Entity {
       address _address;
       uint _data;
   }
   mapping(address => Entity) entityMapping;

   function addEntity(uint _data) public returns(bool success) {
       Entity memory newEntity;
       newEntity._address = msg.sender;
       newEntity._data = _data;
       entityMapping[msg.sender] = newEntity;
       return true;
   }

   function UpdateEntity(address _key, uint _data) public returns(bool success) {
       entityMapping[_key]._data = _data;
       return true;
   }
}
Array
pragma solidity 0.8.0;

contract ArrayStorageAssign {
    
    struct Entity{
        uint data;
        address _address;
    }

    Entity[] entityArray;
    
   
    function addEntity(uint _data) public returns(bool success) {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = msg.sender;
        entityArray.push(newEntity);
        return true;
    }
       
    function updateEntity(uint _index, uint _data) public returns(bool success){ 
        entityArray[_index].data = _data;
        return true;
    }
    
}

When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?
Answer:
Significance: Mapping was appx 8% cheaper so, significant.
Why/why not? The difference is that an array has an order (0, 1, 2, 3, etc…) whereas a mapping does not need to keep track of any order or orders. Thus, the mapping takes less memory/computer processes than an array.

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?
Answer:
Same answer as the first question.
That being said, I noticed that, to initialize the contracts, mapping cost more than the array…even though once initialized, using the mapping was cheaper.
Why? When initializing the contracts, the array is empty with no order to keep track of yet…whereas the mapping, has to be set up. This indicated that setting up a mapping protocol, takes more processes than setting up an empty array.

1 Like

Hi everyone, these are my findings:

I noticed that the gas cost for adding is pretty much the same, which makes sense since mapping is immediate, and so is the array since we’re pushing at the end of it.
Editing is different since mapping will again be immediate, but in the array solution there is a loop, so the consumption will grow with the size of the array, the gas ends up being almost 50% higher.
(At least that’s my understanding, so please correct if I’m wrong :blush: ).

The solutions are implemented below.

This is the solution using only mapping:
addEntity() gas cost: 66058
updateEntity() gas cost at fifth element: 26719

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

contract OnlyMapping {

    struct Entity {
        uint data;
        address _address;
    }

    mapping(address => Entity) entityStructs;

    function addEntity(uint _data) public {
        entityStructs[msg.sender].data = _data;
        entityStructs[msg.sender]._address = msg.sender;
    }

    function updateEntity(uint _data) public {
        entityStructs[msg.sender].data = _data;
    }

}

And this is the solution using only array:
addEntity() gas cost: 71090
updateEntity() gas cost at fifth element: 42246

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

contract OnlyArray {

    struct Entity {
        uint data;
        address _address;
    }

    Entity[] entities;

    function addEntity(uint _data) public {
        entities.push(
            Entity(_data, msg.sender)
        );
    }

    function updateEntity(uint _data) public {
        for (uint i = 0; i < entities.length; i ++) {
            if (entities[i]._address == msg.sender) {
                entities[i].data = _data;
            }
        }
    }
}
1 Like

exactly. sometimes you will find that making a mapping can sometimes even cost more tan looping through an array when the array has few values like one - three. but the more the array grows the more gass it will cost and the mapping becomes far more efficent

an example i can giveis if you think back to the multisig wallet assignemnt. Here most people would check the onlyOnwers with a for loop, looping through the owners array and checking each element against the person calling the function in question. One could make a mapping something like

mapping(address => bool) isOwner

and set this mapping to true for each wallet address that is an owner. However if you do this you will find that instiating the mapping and setting it true for each wallet owner is actually more expensive than looping through an array and checking each member in the scenario where the owners array has like 2 or three members. after this the mapping becomes more efficent.

so when choosing whether to use a mapping or not think first how big my array could get and weigh the decision

Array:

pragma solidity 0.8.0;

contract assignmentArray {

  struct Entity{
    uint data;
    address _address;
}

  Entity[] public entityArray;

    function addEntity(uint _data, address _address) public returns (bool success) {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = _address;
        entityArray.push(newEntity);
        return true;
    }

    function updateEntity(uint _rowNumber, uint _data, address _address) public returns (bool success) {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = _address;
        entityArray[_rowNumber] = newEntity;
        return true;
    }

}

Mapping:

pragma solidity 0.8.0;

contract assignmentMapping {

  struct Entity{
    uint data;
    address _address;
}

    mapping (address => Entity) public entityMapping;

    function addEntity(uint _data) public returns (bool success) {
        entityMapping[msg.sender].data = _data;
        entityMapping[msg.sender]._address = msg.sender;
        return true;
    }

    function updateEntity(uint _data, address _address) public returns (bool success) {
        entityMapping[_address].data = _data;
        entityMapping[_address]._address = _address;
        return true;
    }
    
}

1. When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?

Array consumes the most gas. It is a significant difference:

Array - 88511 gas

Mapping - 66282 gas

Inserting in array costs more gas due to first insertion:

“Gsset - 20000 - Paid for an SSTORE operation when the storage value is set to non-zero from zero.”

2. 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?

Array - 32368 gas

Mapping - 29853 gas

Arrays consume more because arrays in solidity store also length of an array.

1 Like

thank you! @mcgrane5 - interesting point, I actually did have something similar to the isOwner mapping you mentioned. I’ll keep this in mind - as you said, it’s important to think about what kind of use the code will have. Thanks again for your feedback.

pragma solidity 0.8.0;

contract Array{

    struct Entity{
    uint data;
    address _address;
}

  Entity[] public entityarray;

    function addEntity(uint _data, address _address) public returns (bool success) {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = _address;
        entityarray.push(newEntity);
        return true;
    }

    function updateEntity(uint _rowNumber, uint _data, address _address) public returns (bool success) {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = _address;
        entityarray[_rowNumber] = newEntity;
        return true;
    }


pragma solidity 0.8.0;

contract Mapping {

  struct Entity{
    uint data;
    address _address;
}

  mapping (address => Entity) public Entitymapping;

    function addEntity(uint _data) public {
        Entity memory newEntity;
        newEntity.data = _data;
        newEntity._address = msg.sender;
        Entitymapping[msg.sender] = newEntity;
    }

    function updateEntity(address _user, uint data) public returns(uint)
    {
        Entitymapping[_user].data = data;
        return(2);
    }

}

Question 1/
the cost of addEntity for Mapping is 66404 gas
the cost of addEntity for Array is 89102 gas
The mapping solution is cheaper since the array solution uses an iterative strategy which will require more gas.

Question 2/
Array = 32356 gas
Mapping = 27484 gas
The array solution is more expensive since it needs to iterate through the data stored to find the user while the mapping solution uses a key-value strategy.

1 Like

On mapping storage: Execution cost is: 29375 gas
On array storage: Execution cost is: 88489 gas

There is a significant difference between them. The execution from the array storage is three times more than the mapping storage.

The array design used in the first execution 88489 gas and in the others, 71389 gas while the mapping design used 66375 gas in all executions.

Execution cost of updating fifth entry in ArrayVersion: 29324
Execution cost of updating fifth entry in MappingVersion: 24690
After the updating fifth entry in the array version, I can conclude that there’s not a big difference but the mapping version is still the lowest cost and I think this is because, the array storage needs to iterate through all the elements, so if the array contains many elements, the cost will increase.

1 Like

When executing the addEntity function, which design consumes the most gas (execution cost)? Is it a significant difference? Why/why not?

Array solution = 88825 gas
Mapping solution = 66695 gas

The array solution consumed more gas. It was a noticeable amount but not that significant. It’s not significant because we’re only working with a single instance of the struct in both cases which isn’t much data. I’m assuming the main difference in gas costs comes from the intrinsic difference in overhead between the two data types.

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?

Array solution = 42831 gas
Mapping solution = 27300 gas

Again, the array solution consumed more gas. That’s because the updateEntity function has to iterate through every element in the array (in storage) until it finds the one it wants to update – in this case the very last one. The difference between the two is more significant in this scenario because we’re working with more data and having to iterate through the array to find data is not very efficient in this case. This would consume more gas the bigger the array is.
The mapping on the other hand can immediately access the instance of the struct that needs to be updated without any iteration, result in great efficiency and less gas costs.

My code is below:

struct-with-array.sol

pragma solidity 0.8.0;

contract StructWithArray {
    struct Entity{
        uint data;
        address _address;
    }
    Entity[] public entityArray;

    function addEntity(address _address, uint _data) public {
        entityArray.push(Entity(_data, _address));
    }

    function updateEntity(address _address, uint _data) public {
        for(uint i; i < entityArray.length; i++) {
            if(entityArray[i]._address == _address) {
                entityArray[i].data = _data;
            }
        }
    }
}

struct-with-mapping.sol

pragma solidity 0.8.0;

contract StructWithMapping {
    struct Entity{
        uint data;
        address _address;
    }
    mapping (address => Entity) public entityMap;

    function addEntity(address _address, uint _data) public {
        entityMap[_address]._address = _address;
        entityMap[_address].data = _data;
    }

    function updateEntity(address _address, uint _data) public {
        entityMap[_address].data = _data;
    }
}
1 Like

Mapping Solution (i commented out the boolean for the sake of the homework)

pragma solidity 0.8.0;
// SPDX-License-Identifier: MIT

contract StoreStructWithMapping{

    struct Entity{
        uint data;
        address _Address;
        //bool isKnown;
    }
    
    mapping(address => Entity) EntityStruct;

    function addEntity( uint _data) public{
        //require(EntityStruct[msg.sender].isKnown == false);
        EntityStruct[msg.sender].data = _data;
        EntityStruct[msg.sender]._Address = msg.sender;
       // EntityStruct[msg.sender].isKnown = true;
    }

    function UpdateEntity( uint _data ) public {
       // require(EntityStruct[msg.sender].isKnown == true);
        EntityStruct[msg.sender].data = _data;
    }

}


Array Solution

pragma solidity 0.8.0;
// SPDX-License-Identifier: MIT 

contract ArrayStructAssignment{

    struct Entity{
        uint _data;
        address _address;
    }

    Entity[]  entityStructs;

    function addEntity( uint _data) public  {
        entityStructs.push(Entity(_data, msg.sender));
    }
    
    function updateEntity(uint _id ,uint _data) public returns (uint, address) {
        //loop through the array to find the index corresponding to the id
        for( uint i=0; i<entityStructs.length; i++){
            if( _id == i ){
                entityStructs[i]._data = _data;
                return (entityStructs[i]._data, entityStructs[i]._address);
            }
            else {
                continue;
            }
        }
    }

}

}

The addEntity function using a mapping costs

66786 gas

The addEntity function using an array costs

88190 gas

the array solution consumes around 30% more gas than wih a mapping, considering it a pretty significant increase.

In the mapping solution, upon adding 5 new entities, it costed 333,930 gas, and changing the data of the 5th address costed 29035 gas.

In the array solution, upon adding 5 new entities, it costed 372,550 gas, the first element costing 88190 gas and the elements after costing 71090 gas, and changing the data of the 5th address costed 33551 gas.

The array execution consumes more gas since it has to iterate through the list to find the right index, whereas a map simply uses the inputted key to find the value and doesn’t have to search through a whole list.

storage_mapping.sol

pragma solidity 0.8.0;

contract storageMapping {
    struct Entity {
        uint data;
        address _address;
    }
    mapping(address => Entity) entityMap;

    function addEntity(uint newData) public {
        Entity memory newEntity;
        newEntity.data = newData;
        newEntity._address = msg.sender;
        entityMap[msg.sender] = newEntity;
    }

    function updateEntity(uint newData) public {
        entityMap[msg.sender].data = newData;
    }
}

storage_array.sol

pragma solidity 0.8.0;

contract storageArray {
    struct Entity {
        uint data;
        address _address;
    }
    Entity [] entityArray;

    function addEntity(uint newData) public {
        Entity memory newEntity;
        newEntity.data = newData;
        newEntity._address = msg.sender;
        entityArray.push(newEntity);
    }

    function updateEntity(uint newData) public {
        for (uint i = 0; i < entityArray.length; i++)
        {
            if (entityArray[i]._address == msg.sender) {
                entityArray[i].data = newData;
            }
        }
    }
}
  1. the contract with only array consumes more gas, but it is not significant difference, which is due to the internal implementation between the hash-map in mapping and the append-list in array

  2. mapping-only contract: 26719 array-only contract: 42246
    because we have to loop the entire list to locate the entity address when use array-only contract

1 Like