Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More flexibility to measure gas usage for tests #2429

Closed
RickVM opened this issue Jul 21, 2022 · 3 comments
Closed

More flexibility to measure gas usage for tests #2429

RickVM opened this issue Jul 21, 2022 · 3 comments
Labels
A-cheatcodes Area: cheatcodes A-gas-snapshots Area: gas snapshotting/reporting C-forge Command: forge Cmd-forge-script Command: forge script Cmd-forge-test Command: forge test D-hard Difficulty: hard P-low Priority: low T-feature Type: feature

Comments

@RickVM
Copy link

RickVM commented Jul 21, 2022

Component

Forge

Describe the feature you would like

I would like a way to do specific pre-test setups without it counting towards the gas-usage for that test.
Setup() is fine for a lof of cases, but I require a bit more flexibility to effectively write various test scenarios.

I'm open for ideas but can propose a solution:
A cheatcode that allows us to reset gas measurements from that point on during a test.
This will give users the most flexibility regarding what they want to measure.

    function testRemoveStates() public {
        uint256 amount = 100;
        States[] memory states = fillStates(100);
        vm.resetGas(); // I only want to measure the performance of removeStates in this scenario
        removeStates(states);
    }

Context:
I have a contract that keeps track of data, initialized with an empty state and various general parameters during setup(). (Struct[] with specific data)

On this contract, I want to run various tests to measure gas performance, e.g. for data retrieval and deletion.
Some tests would contain more values, some less. I do not want the part where I fill the state to be part of the gas measurements. Right now I'm finding myself needing to write abstract contracts with helper functions and extending that contract multiple times for each Test case (eg filled with 100, 1000, 10000 states), far from ideal

Additional context

No response

@RickVM RickVM added the T-feature Type: feature label Jul 21, 2022
@gakonst gakonst added this to Foundry Jul 21, 2022
@gakonst gakonst moved this to Todo in Foundry Jul 21, 2022
@RickVM
Copy link
Author

RickVM commented Jul 21, 2022

I just noticed that the skip and vm.prank functions also add to the measured gas usage.
That's an additional reason to implement some kind of reset feature to allow for more fine-grained measurements :)

function testRemoveStates() public {
        skip(900000);
        vm.prank(theMint);
       // registry.removeOldData(removeKeys);
    }```

@onbjerg
Copy link
Member

onbjerg commented Jul 21, 2022

skip is a helper function in Forge Std, not an actual cheatcode, so it will impact gas consumption. vm.prank only impacts gas consumption because of Solidity opcodes to perform the call, the actual cheatcode logic itself does not add to gas consumption - not easy to remove since we can't reasonably have perfect knowledge of the emitted bytecode for the call

Currently this is not really possible with the EVM implementation we use since it's not just setting some gas used variable to 0, there is a lot of other considerations about cold/warm accoutns and storage slots. Warm storage slots and accounts also change other state of accounts that is used to figure out what to persist and so on, so it's definitely a hard challenge. I know it's been requested a lot though, so definitely worth exploring a lot more at some point

Currently the best we have is forge test --gas-report which will give you the gas cost of individual function calls, but again it may vary dependign on cold/warm accounts and storage slots.

Edit: A note on the API, I don't think vm.resetGas makes a lot of sense since you might have multiple points in your test you want to measure, so I think better UX would be something like vm.startGasMeasurement("some span name") and vm.stopGasMeasurement() where the span name would be displayed in a report (names suck but that's a tomorrow problem)

@mds1
Copy link
Collaborator

mds1 commented Mar 9, 2023

Going to close this per the above comment. If there is a need for better ways to measure gas usage than what's currently available, we'll need to come up with a good UX and implementation and create a new issue with that proposal

@mds1 mds1 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 9, 2023
@github-project-automation github-project-automation bot moved this from Todo to Done in Foundry Mar 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes A-gas-snapshots Area: gas snapshotting/reporting C-forge Command: forge Cmd-forge-script Command: forge script Cmd-forge-test Command: forge test D-hard Difficulty: hard P-low Priority: low T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

3 participants