dtolnay / quote

Rust quasi-quoting
Apache License 2.0
1.32k stars 90 forks source link

Push to existing TokenStream for speed #235

Closed rMazeiks closed 1 year ago

rMazeiks commented 1 year ago

Code like this:

let type_definition = quote! {...};
let methods = quote! {...};

let tokens = quote! {
    #type_definition
    #methods
};

Is a tiny bit inefficient, because it's creating 2 intermediate TokenStreams, only to interpolate them and destroy them later. This allocation is not free, and I have in fact seen people trying to optimize it away, making code unreadable in the process.

What if there was a quote_into macro? Instead of allocating a new TokenStream, it would accept a &mut TokenStream to push to. This would avoid the unnecessary allocations.

I made a prototype for this idea – the syntax is described here: https://crates.io/crates/quote_into

In a really simple case with only a few interpolations, quote_into seems to be ~1.6x faster.

In a more extreme case with 100-deep recursion, it's ~30x faster than quote.

For more benchmark details, see https://gitlab.com/reinis-mazeiks/quote_into/-/tree/main/benches

Does this belong in quote or should it be in a separate crate? I will appreciate any feedback. Thanks!

dtolnay commented 1 year ago

This was proposed previously in #137.