Attribute procedure macro slower than derive proc macro?

I have a lot of structs which I need to process via the proc macro. The output is pretty much the struct as-is (with some extra annotations on it) plus some extra code. I want to use attribute macros -- mostly, because of nicer "API" I can offer (derive would work as fine, it's just that with attribute macro I can pass extra arguments instead of a separate attribute with arguments).

There are potentially two strategies I can process them:

  1. Handle with proc macro attribute. Parse input, remove attributes I handle, then render it back + extra code.
  2. Two step processing: desugar to derive macro first, then generate extra code. Let the compiler strip attributes I handled [^1].

I created a test to bench both variants and the latter seems to consistently win (it's like ~9 seconds vs ~7.3 seconds) and I wonder why. Is it because variant #1 has to render structs back and in #2 compiler is more efficient at stripping attributes?

Here is the code: https://github.com/idubrov/proc-macro-madness (run ./bench.sh, which repeatedly invokes cargo).

I noticed that difference while experimenting on our real code (where difference was something like 40 seconds vs 33 seconds), so it is not a completely arbitrary test.

[^1]: So the second variant would be something like:

#[myattribute(args)]
struct X {
  #[my_tag]
  field: usize,
}

would "desugar" to:

#[derive(My)]
#[myattribute(args)]
struct X {
  #[my_tag]
  field: usize,
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.