Skip to content

Improve parser performance#21

Merged
darthmaim merged 1 commit intomainfrom
feature/parser-performance
Feb 21, 2026
Merged

Improve parser performance#21
darthmaim merged 1 commit intomainfrom
feature/parser-performance

Conversation

@darthmaim
Copy link
Member

This doubles the performance for text only inputs, and is also quite a bit faster for other markup.

Before

 ✓ test/parser.bench.ts > text only 2751ms
     name                                         hz     min      max    mean     p75     p99    p995    p999      rme  samples
   · parse                              1,394,333.70  0.0003  11.2692  0.0007  0.0005  0.0014  0.0023  0.0245  ±10.86%   697167
   · parse({ includePosition: false })  2,463,950.83  0.0002   4.1256  0.0004  0.0004  0.0009  0.0022  0.0133   ±1.97%  1231976

 ✓ test/parser.bench.ts > simple markup 1411ms
     name                                       hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · parse                              362,314.67  0.0022  0.5758  0.0028  0.0027  0.0039  0.0054  0.0490  ±0.78%   181158
   · parse({ includePosition: false })  432,193.63  0.0018  2.2539  0.0023  0.0023  0.0032  0.0040  0.0385  ±1.19%   216097

 ✓ test/parser.bench.ts > complex markup 1209ms
     name                                     hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · parse                              4,653.99  0.1789  3.8645  0.2149  0.2105  0.4692  0.8598  1.5449  ±2.10%     2327
   · parse({ includePosition: false })  5,739.96  0.1511  0.8865  0.1742  0.1781  0.3018  0.4014  0.7819  ±0.80%     2870

After

 ✓ test/parser.bench.ts > text only 3387ms
     name                                         hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · parse                              2,695,008.51  0.0002  5.7137  0.0004  0.0003  0.0009  0.0021  0.0057  ±2.54%  1347505
   · parse({ includePosition: false })  4,138,253.35  0.0002  0.7431  0.0002  0.0003  0.0003  0.0004  0.0012  ±0.77%  2069127

 ✓ test/parser.bench.ts > simple markup 1503ms
     name                                       hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · parse                              520,265.73  0.0015  0.6584  0.0019  0.0019  0.0027  0.0031  0.0208  ±0.67%   260134
   · parse({ includePosition: false })  594,701.55  0.0012  2.5628  0.0017  0.0016  0.0024  0.0033  0.0308  ±2.20%   297351

 ✓ test/parser.bench.ts > complex markup 1210ms
     name                                     hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · parse                              5,785.16  0.1487  2.7702  0.1729  0.1697  0.3173  0.5834  1.2858  ±1.56%     2893
   · parse({ includePosition: false })  6,961.24  0.1218  0.8324  0.1437  0.1439  0.2086  0.2831  0.6341  ±0.73%     3481

Changes

  • Don't value.slice(i) on every iteration, instead work with value[i] if possible
  • Peek at the next character before using regex
  • Keep track of current children in variable (instead of getting them of the stack everytime)
  • Use indexOf instead of regex search to find next potential node

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the Guild Wars 2 markup parser for better performance, particularly for text-only inputs which see a ~2x improvement. The changes refactor the main parsing loop to reduce string allocations and regex operations without changing the parser's behavior.

Changes:

  • Replaced the currentChildren() helper function with a tracked children variable that's updated when pushing/popping from the stack
  • Optimized character-by-character processing by peeking at value[i] before doing expensive string slicing and regex matching
  • Replaced regex-based search for next nodes with faster indexOf calls for < and \n characters

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/parser/src/parser.ts Refactored main parsing loop with performance optimizations: tracks children array as variable, peeks at characters before regex matching, uses indexOf for finding next nodes
.changeset/silly-symbols-own.md Added changeset documenting the performance improvement as a patch release

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@darthmaim darthmaim added this pull request to the merge queue Feb 21, 2026
Merged via the queue into main with commit 91b5274 Feb 21, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants