perf(jsdoc): skip should_attach_jsdoc when no remaining comments (#22409)

## Summary

`JSDocBuilder::retrieve_attached_jsdoc` is called for every AST node during the semantic build. Even when the source contains no JSDoc comments, the per-node `should_attach_jsdoc(kind)` `matches!` over 33 variants still runs.

This adds a fast-path early return when `not_attached_docs` is empty — true for files with no JSDoc, and for the tail of every walk once all comments have been attached — and marks `retrieve_attached_jsdoc` `#[inline]` so the guard fuses into `SemanticBuilder::create_ast_node`.

## Measurements

`xcrun xctrace record --template 'Time Profiler'`, semantic stage on the standard benchmark inputs. Profile binary built with `--profile release-with-debug`.

`retrieve_attached_jsdoc` self-time:

| file | before | after |
|---|---|---|
| antd.js (6.7M, sparse JSDoc) | 2.59% | **0.04%** |
| checker.ts (2.8M, JSDoc throughout) | 3.23% | **0.17%** |

Hot-path bundle (retrieve + should_attach + create_ast_node) drops ~2pp on both files. Wall-time on 50 iters of parse+semantic: antd −9%, checker −8%, cal.com.tsx −5%.

## Notes

- `should_attach_jsdoc` still runs when there are comments left to attach, so behavior is unchanged.
- The `#[inline]` lets LLVM fuse the empty-map check into the visitor body, which is what amplifies the win on JSDoc-heavy inputs (the guard fires once all comments are placed).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
Boshen committed 2026-05-15 15:31:11 +00:00
1 parent 217d7d8a1c
commit dbbc059eff
1 file changed
+7
+7
View File
@@ -111,7 +111,14 @@ impl<'a> JSDocBuilder<'a> {
//
// If one day we want to add a performance-affecting kind,
// we might as well give up pre-flagging architecture itself?
#[inline]
pub fn retrieve_attached_jsdoc(&mut self, kind: &AstKind<'a>) -> bool {
// Fast path: when there are no remaining JSDoc comments to attach, skip the
// `should_attach_jsdoc` discriminant check entirely. This is the common case for
// files with no JSDoc, and for the tail of every walk once all comments are attached.
if self.not_attached_docs.is_empty() {
return false;
}
if should_attach_jsdoc(kind) {
let start = kind.span().start;
if let Some(docs) = self.not_attached_docs.remove(&start) {