Skip to content

Commit a058694

Browse files
perf: pre-declare position on delete factory
Problem: the strikethrough handler creates each delete node as a fresh object literal, then mdast-util-from-markdown's enter() sets node.position afterwards. V8 treats that late assignment as a shape change, so every delete node walks through two hidden classes instead of one. Core nodes already avoid this by declaring position up front; without the same trick on extension nodes, GFM trees end up mixing two layouts and downstream tree walks lose monomorphic dispatch. Goal: declare position on the delete literal at construction so V8 keeps a single hidden class for delete from start to finish. Changes: - lib/index.js: trailing position: undefined on the delete literal in enterStrikethrough. Notes: pairs with the matching core change in syntax-tree/mdast-util-from-markdown#53; merged on its own this branch is a no-op. Validated with npm test (build, format, 100% coverage, 13 of 13 tests in dev and prod). Bench (local harness, 3-run median-of-medians, GFM tokenizer and mdast extensions stacked, with the core branch and three sibling extension branches checked out alongside this one): Input: one paragraph of 1000 ~~strike~~ runs. On the baseline this is the second-largest mdast-layer share in the GFM corpus (full 11.0 ms, tokenize-only 5.2 ms; the mdast layer is the gap between those two). setup delta vs main core branch alone +14.6% core branch with this paired +2.6% The 12-point swing is the recovery this branch is designed to produce: delete nodes now share the core layout, so tree walks stay monomorphic. A drift floor measured separately (main against itself, no code change) ran at +4 to +12 percent across most GFM inputs on this machine in the same window, so the +2.6 percent residual sits inside bench noise.
1 parent 8c8c836 commit a058694

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

lib/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ export function gfmStrikethroughToMarkdown() {
7171
* @type {FromMarkdownHandle}
7272
*/
7373
function enterStrikethrough(token) {
74-
this.enter({type: 'delete', children: []}, token)
74+
// Trailing `position: undefined` keeps the delete hidden class stable;
75+
// mdast-util-from-markdown's enter() patches the field to a real value,
76+
// but the property already exists, so no shape transition fires.
77+
this.enter({type: 'delete', children: [], position: undefined}, token)
7578
}
7679

7780
/**

0 commit comments

Comments
 (0)