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

Remove redundant memory usage in Checkpoints #4540

Merged
merged 8 commits into from Jan 17, 2024

Conversation

0xVolosnikov
Copy link
Contributor

@0xVolosnikov 0xVolosnikov commented Aug 25, 2023

Some optimizations, as i wrote in #4512 (comment)

  • removed redundant memory usage

Fixes LIB-1187

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@changeset-bot
Copy link

changeset-bot bot commented Aug 25, 2023

🦋 Changeset detected

Latest commit: 6ad3f63

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@0xVolosnikov 0xVolosnikov marked this pull request as draft August 25, 2023 21:08
@0xVolosnikov
Copy link
Contributor Author

0xVolosnikov commented Aug 25, 2023

@Amxx (I apologize for the tagging, this is originally your code, judging by the Git Blame)

I'm very interested in why the library relies on non-strictly increasing order everywhere, like here:

if (_unsafeAccess(self, mid)._key > key) {

Based on the descriptions of the functions, it looks like they were created with the expectation that there may be elements with the same keys:

* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.

At the same time, the insertion implementation does not allow adding multiple elements with the same key. This, of course, can be done manually by forcibly adding an element to the array. But you can also add an incorrect element (with a decreasing key) in such way. So it doesn't look like there should be multiple elements with the same key in an array in normal use of the library.

If the array is strictly ordered, then it is strange that the search does not handle the case when it hits the desired key (the case of equality). In the worst case, if the array is N long and the target is exactly in the middle, the current implementation will do something like log2(n) - 1 excessive reads of cold storage slots (~2100 gas each).

So with simple example like (keys) [2, 3, 5, 7, 11, 12, 13, 14] i tried two implementations of lowerLookup: current and with separate handling of equality. Gas estimations for lowerLookup(11) (including 21000 “base fee”):
current version: 31712
modified version: 26762

I'm interested if there's a reason not to make such changes.

UPD: created a separate PR for this question: #4544

@Amxx
Copy link
Collaborator

Amxx commented Aug 28, 2023

I'm very interested in why the library relies on non-strictly increasing order everywhere

That is an interresting question. We always try to be on the safe(r) side. Given that the simplest version of the code (the one that doesn't handle equality) is the safest (it works with more structure) it felt like the better option.

Now, it may reasonable to assume that this will only be used with structures produced using _insert, and in that case we can indeed optimise some runtime cost, at the expense of more complexe code (and some more deployment cost)

@frangio WDYT?

@0xVolosnikov 0xVolosnikov changed the title Optimize checkpoints Remove redundant memory usage in Checkpoints Aug 28, 2023
@0xVolosnikov
Copy link
Contributor Author

force-pushed: removed unchecked blocks for safe arithmetic, since this is a standalone change and would probably be better done in another pull request

@0xVolosnikov
Copy link
Contributor Author

Created a separate pull request for this question:
#4544

@0xVolosnikov 0xVolosnikov marked this pull request as ready for review August 28, 2023 11:49
Amxx
Amxx previously approved these changes Sep 6, 2023
@Amxx
Copy link
Collaborator

Amxx commented Sep 6, 2023

@frangio Do we merge that for 5.0, or is 5.0 frozen and that goes into 5.1?

@frangio
Copy link
Contributor

frangio commented Sep 7, 2023

I would put this in the bin for 5.1 with other optimizations we haven't merged yet.

@ernestognw ernestognw added this to the 5.1 milestone Oct 24, 2023
Copy link
Member

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, will wait on @Amxx since a couple of changes were made after 5.0

@ernestognw ernestognw requested a review from Amxx January 16, 2024 23:16
@Amxx Amxx merged commit d2ba1f6 into OpenZeppelin:master Jan 17, 2024
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants