Skip to content

Eliminate a bunch of recursion #567

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

Merged
merged 5 commits into from
Jul 16, 2023

Conversation

apoelstra
Copy link
Member

This introduces a new iter module with facilities for iterating over tree structures, and uses it to eliminate a bunch of recursion.

There's a lot more "obvious" work after this, so I figured I'd PR this now for review and then do followup ones if it's accepted.

Then there's some less obvious work around getting rid of the recursion in Expression::from_str and tightening up the memory allocation/locality there, and some even less obvious work in improving memory allocation/locality in Miniscript. But even if those later stages don't work out, this is a step in the right direction because it eliminates a bunch of stack overflow vectors, and reduces the amount of code.

@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch from 311135f to 6250791 Compare July 14, 2023 23:50
Introduces the new `iter` module which provides iteration abilities over
various tree-like structures. This is largely copied from
rust-simplicity, but is both simpler (because there is no sharing) and
more complicated (because we need to handle n-ary nodes, not just binary
ones).

This currently uses Arc<[T]> in a number of places; we should eventually
replace these with some sort of ArrayVec-type structure.

Partially verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
We cannot verify signatures from co-authors, and some of the co-authors attributed to this commit require their commits to be signed.
This is a breaking change because we no longer implement `ForEachKey` on
`Terminal`. But IMHO we should never have implemented that trait (or any
trait, really..) directly on `Terminal`. The fact that we did was just
an implementation detail of how we used to do a lot of iteration.
@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch 3 times, most recently from 654e234 to 0576007 Compare July 15, 2023 14:48
Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

Some commits are empty? Is that intentional.

ACK 0576007.

_ => {}
}
}
true
Copy link
Member

Choose a reason for hiding this comment

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

After reading about possible compiler optimization speedup from using functional style code. I feel we can write this as:

  self.pre_order_iter().all(|ms| match ms.node {
      Terminal::PkK(ref p) => pred(p),
      Terminal::PkH(ref p) => pred(p),
      Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
          keys.iter().all(|k| pred(k))
      }
      _ => true,
  })

Copy link
Member

Choose a reason for hiding this comment

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

@sanket1729
Copy link
Member

Agreed, this is a step in the right direction.

@sanket1729
Copy link
Member

I can merge these and address the nits in a follow up PR. Just waiting for your response about the empty commits.

@apoelstra
Copy link
Member Author

@sanket1729 no, I'll remove the empty commits. I believe those occur during rebasing when my gpg agent fails to sign a commit.

I'll do that and then you can merge this. For optimizations I think we should first introduce a wider set of benchmarks (miniscript parsing from string, decoding from script, serializing to string, encoding to script, then some borderline-trivial key conversions etc).

This is again a breaking change because we remove the trait impl from
`Terminal`, but again I don't think the trait impl should've existed.

This also exposed an "off-label" use of `real_translate_pk` to convert
context types as well as pk types, which I apparently explicitly reviewed
and ACKed when reviewing rust-bitcoin#426, but which in retrospect looks a little
funny. Rename this function to translate_pk_ctx so it's clear that it's
doing two jobs.
As usual, we remove a method of the same name from `Terminal`, which is
a breaking change.
As always, dropping the same method from Terminal
@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch from 0576007 to 67e91b9 Compare July 16, 2023 13:37
Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

reACK 67e91b9

@sanket1729 sanket1729 merged commit 9cf6e9d into rust-bitcoin:master Jul 16, 2023
@apoelstra apoelstra deleted the 2023-07--dag-overhaul branch July 17, 2023 13:22
@@ -0,0 +1,93 @@
// Written in 2023 by Andrew Poelstra <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

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

Hey @apoelstra, I saw this line and wondered if you added it as a habit or if I have been annoying you by removing them? Or was this PR just before we discussed all that? Cheers.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it predates your PR to remove these. I would've just mildlessly copied the line from other files.

I'm certainly not annoyed :).

Copy link
Member

Choose a reason for hiding this comment

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

Sweet man, cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants