question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add a function for shrinking memory arrays

See original GitHub issue

🧐 Motivation Solidity in-memory arrays can’t grow, because reallocation would be expensive and difficult to perform safely. But they can safely shrink.

Quite often a memory array needs to be passed around with a length variable to simulate a dynamic data structure. In some cases it’s only ever decreasing, e.g. when items are popped and consumed. This is both inefficient and dangerous, because Solidity only checks array.length when sanity-checking accessed indexes, it doesn’t know about the other variable.

šŸ“ Details Add a function to library Arrays:

function shrinkArray(uint256[] memory array, uint newLength) internal pure returns (uint256[] memory) {
    require(newLength <= array.length, "Array: length after shrinking larger than before");
    /// @solidity memory-safe-assembly
    assembly {
        mstore(array, newLength)
    }
    return array;
}

Edit: I think that shrinkArray is too verbose, just shrink would be a better name, it’d be called by Array.shrink(myArray, len); or when using Array for uint256[], just by myArray.shrink(len).

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:13 (13 by maintainers)

github_iconTop GitHub Comments

1reaction
frangiocommented, Jun 24, 2022

I’m concerned about the interaction with Solidity optimizations. I think that as long as the assembly block isn’t marked ā€œmemory-safeā€ things should be fine, but there is some risk… See the recent compiler bug related to memory and assembly.

1reaction
Amxxcommented, Jun 21, 2022

You are bechmarking a lot of extra stuff

        uint256[] memory array = new uint256[](100);
        uint256 sum1;
        uint256 sum2;
        uint256 sum3;

        uint gas1 = gasleft();
        for(uint i = 0; i < array.length; i++) {
            sum1 += array[i];
        }
        gas1 -= gasleft();

        uint gas2 = gasleft();
        unchecked {
            uint length = array.length;
            for(uint i = 0; i < length; i++) {
                sum2 += array[i];
            }
        }
        gas2 -= gasleft();

        uint gas3 = gasleft();
        while(array.length > 0) {
            sum3 += popArray(array);
        }
        gas3 -= gasleft();

With my compiler settings I get:

  • iteration: 24442
  • iteration with unchecked + caching: 11950
  • popping: 21431

The basic iteration mload the length for every loop (and so does the popping) … that cost a lot. The basic iteration does safe math on i++ and bound checks on array[i] … that also cost a lot. there two account for more than half of the total cost.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Extending and shrinking array using realloc - Stack Overflow
Save this question. Show activity on this post. I'm trying to write a program which first dynamically initialises a queue array for 100...
Read more >
Shrink array to save memory - c++ - Arduino Stack Exchange
This is a common question when designing software. The simple answer (rule of thumb) is statically allocate the maximum size of the array....
Read more >
Shrink dynamic arrays with delete[] operator - Google Groups
Allocate memory using the std::malloc function and shrink the array using the std::realloc function. Create a new array, copy the useful objects and...
Read more >
Resizeable Array (C / C++) - Swamy says ... - Google Sites
The Resizeable-array scheme presented here allows for growing (and shrinking) without the need for as expensive a memory copy as with conventional dynamicĀ ......
Read more >
Guidelines and examples of array formulas - Microsoft Support
An array formula (one that spans multiple cells) can do calculations on rows and columns of cells where you might otherwise need to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found