Profiling a proc-macro

Hello everyone!

In order to learn how to use proc macros, I've implemented an LR(1) parser generator. It works, but it's really slow and I'm trying to figure out why.

How could I possibly do a profiling run using perf or flamegraph, given that no binary is produced ?

Thanks in advance.

You could implement a toy grammar in a new cargo --bin project that depends on your parser generator, and profile that.

Since it's a parser generator, that shouldn't be a lot of work.

Well I'm not trying to profile the generated parsers, but the generator itself (i.e the code that generates the parser)

Ok let's take a step back.

Any macro consists of 2 parts, the generated code and the generator code.

So if I understand you correctly (and contrary to what I thought earlier) it's the generator code that's slow.

In that case what I would do is still create a new project and write a toy grammar, because the generator code runs while that binary crate is being compiled. But indeed, it's not some loose binary that can be profiled.

If the generator code is run within the rustc process (which I'm not sure of but it well might be) then it's going to be very difficult to get coherent profiling data on just the generator code.

I'd advise to do the following:

  • Pull the main proc-macro logic into separate function (or even separate crate), using proc_macro2::TokenStream for input and output; the proc-macro itself would then consist of only one line, like implementation(input.into()).into().
  • Make a binary which generates the input for the macro as proc_macro2::TokenStream - this can be done by using FromStr implementation, i.e. via str::parse - and outputs the macro output somehow.
  • Profile this binary.
3 Likes

That did the trick ! Thank you.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.