Skip to content

Commit 7bef571

Browse files
perf: pre-declare position on footnote factories
Problem: the footnote handlers build footnoteReference and footnoteDefinition nodes as fresh literals, then mdast-util-from- markdown's enter() sets node.position afterwards. V8 treats that late assignment as a shape change, so each 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 with mixed layouts and tree walks pay a polymorphic-dispatch cost. Goal: declare position on both footnote literals at construction so V8 keeps a single hidden class per node type. Changes: - lib/index.js: trailing position: undefined on the footnoteReference literal in enterFootnoteCall. - lib/index.js: trailing position: undefined on the footnoteDefinition literal in enterFootnoteDefinition. 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, 22 of 22 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: a document with 1000 footnote definitions and 1000 references to them. On the baseline this scenario carries a modest mdast-layer share (full 78.0 ms, tokenize-only 62.4 ms) but every footnote node still pays the shape-change cost without the pre-declare. setup delta vs main core branch alone +19.5% core branch with this paired +13.0% The 6.5-point swing tracks the recovery on footnote nodes. A drift floor measured separately ran at +4 to +12 percent across most GFM inputs on this machine in the same window, putting the +13 percent residual at the upper end of that noise band.
1 parent 8ff7529 commit 7bef571

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

lib/index.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ function enterFootnoteCallString() {
3131
* @type {FromMarkdownHandle}
3232
*/
3333
function enterFootnoteCall(token) {
34-
this.enter({type: 'footnoteReference', identifier: '', label: ''}, token)
34+
// Trailing `position: undefined` keeps the footnoteReference hidden class
35+
// stable; mdast-util-from-markdown's enter() patches the field to a real
36+
// value but the property already exists, so no shape transition fires.
37+
this.enter(
38+
{type: 'footnoteReference', identifier: '', label: '', position: undefined},
39+
token
40+
)
3541
}
3642

3743
/**
@@ -47,8 +53,16 @@ function enterFootnoteDefinitionLabelString() {
4753
* @type {FromMarkdownHandle}
4854
*/
4955
function enterFootnoteDefinition(token) {
56+
// See enterFootnoteCall above for the rationale on the trailing
57+
// position field.
5058
this.enter(
51-
{type: 'footnoteDefinition', identifier: '', label: '', children: []},
59+
{
60+
type: 'footnoteDefinition',
61+
identifier: '',
62+
label: '',
63+
children: [],
64+
position: undefined
65+
},
5266
token
5367
)
5468
}

0 commit comments

Comments
 (0)