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

Replace macros with traits; other cleanups #650

Merged
merged 7 commits into from
Mar 5, 2024

Conversation

apoelstra
Copy link
Member

There are several macros we use to implement functions when our Pk types satisfy a large bundle of trait conditions. There is a trick rust-lang/rust#20671 (comment) that we can use instead.

While I'm at it, do several other small cleanups.

As a weekend project I rewrote the expression module and was able to get a 10-15% speedup on parsing miniscripts, while eliminating recursion and simplifying the algorithms. I am still working on cleaning up the code and improving the error handling. This is the first set of commits from that branch, which should be simple and uncontroversial.

These are fairly common leaf nodes and throughout the codebase we tend
to reconstruct and typecheck them. It is faster and clearer to just have
constants.
This eliminates a bunch of error paths, which is nice.
In a later commit we will rewrite Terminal::from_tree entirely. But the
beginning and end (which parse out and then apply "wrappers", the
modifiers added to miniscript fragments using `:`) will remain the same.
Pull this logic out into a pair of helper functions.

This also reduces the total amount of indendentation, reduces function
size, and reduces the total number of variables in scope at once. So
this is a useful refactor independent of any future work.
On my system these show (the last two lines are the new ones)

test expression::benches::parse_tree         ... bench:         860 ns/iter (+/- 44)
test expression::benches::parse_tree_deep    ... bench:       1,481 ns/iter (+/- 66)
test miniscript::benches::parse_segwit0      ... bench:       9,205 ns/iter (+/- 77)
test miniscript::benches::parse_segwit0_deep ... bench:      23,003 ns/iter (+/- 248)

As mentioned in the last commit message, these numbers are 10-20x the
numbers for parsing expressions, meaning that optimizing the expression
parser by itself will not get us a large performance boost.
@apoelstra apoelstra force-pushed the 2024-03--cleanups branch from f5c35c3 to 164bde9 Compare March 4, 2024 22:44
@apoelstra
Copy link
Member Author

Rebased.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

ACK f22dc3a

impl_from_str!(
Bare<Pk>,
type Err = Error;,
impl<Pk: crate::FromStrKey> core::str::FromStr for Bare<Pk> {
Copy link
Member

Choose a reason for hiding this comment

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

nit: I rekon we should import FromStrKey and use the more terse <Pk: FromStrKey> since inline trait bounds are noisy enough as it is.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. Will do this as a followup (or you are welcome to).

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.

ACK 164bde9. Are you taking a performance refactor stab at rust-miniscript?

@apoelstra
Copy link
Member Author

ACK 164bde9. Are you taking a performance refactor stab at rust-miniscript?

Sorta -- my original goal was to test a more-efficient tree structure, starting with expression::Tree because nobody directly uses that or cares if I wreck up its API. That was successful, and as a side effect of doing it I was able to get rid of recursion during parsing and also dramatically improve the error messages. (Not a hard thing to do; the existing errors are basically stringly-typed throughout the codebase :)).

From there I've gotten a bit sidetracked improving the errors in this crate and improving other things (like these macros) which I ran into. My next PR will bring in a new WithSpan error type which is able to keep track of locations in the original string being parsed, and either use it in the typechecker errors, or in the new expression module.

@apoelstra apoelstra merged commit 95b9337 into rust-bitcoin:master Mar 5, 2024
16 checks passed
@apoelstra apoelstra deleted the 2024-03--cleanups branch March 5, 2024 14:22
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.

3 participants