diff --git a/eksml/BENCHMARKS.md b/eksml/BENCHMARKS.md
index 815210a..0fa0c55 100644
--- a/eksml/BENCHMARKS.md
+++ b/eksml/BENCHMARKS.md
@@ -1,6 +1,6 @@
# Benchmarks
-All benchmarks run via [Vitest bench](https://vitest.dev/guide/features.html#benchmarking) on Node.js. Fixtures range from ~100 B to ~30 KB of real-world XML (RSS feeds, Atom feeds, SOAP envelopes, Maven POMs, XMLTV EPGs), plus a ~10 KB synthetic attribute-heavy stress document. Full benchmark source is in [`bench/`](./bench/).
+All benchmarks run via [Vitest bench](https://vitest.dev/guide/features.html#benchmarking) on Node.js. Fixtures range from ~100 B to ~30 KB of real-world XML (RSS feeds, Atom feeds, SOAP envelopes, Maven POMs, XMLTV EPGs), plus a ~10 KB synthetic attribute-heavy stress document and a generated 10 MB product catalogue (with 50 MB and 250 MB variants via `pnpm bench:large`). Full benchmark source is in [`bench/`](./bench/).
Run them yourself:
@@ -24,33 +24,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 71,409 op/s |
+ 71,601 op/s |
— |
| tXml |
- 35,936 op/s |
- 1.99x slower |
+ 35,030 op/s |
+ 2.04x slower |
| htmlparser2 |
- 14,707 op/s |
- 4.86x slower |
+ 14,668 op/s |
+ 4.88x slower |
- | xml2js |
- 5,564 op/s |
- 12.83x slower |
+ fast-xml-parser |
+ 5,562 op/s |
+ 12.87x slower |
- | fast-xml-parser |
- 5,469 op/s |
- 13.06x slower |
+ xml2js |
+ 5,476 op/s |
+ 13.08x slower |
| @xmldom/xmldom |
- 3,527 op/s |
- 20.25x slower |
+ 3,484 op/s |
+ 20.55x slower |
@@ -71,33 +71,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 1,661,243 op/s |
+ 1,633,153 op/s |
— |
| tXml |
- 1,008,262 op/s |
- 1.65x slower |
+ 965,270 op/s |
+ 1.69x slower |
| htmlparser2 |
- 543,433 op/s |
+ 533,389 op/s |
3.06x slower |
| fast-xml-parser |
- 165,332 op/s |
- 10.05x slower |
+ 173,701 op/s |
+ 9.40x slower |
| xml2js |
- 129,948 op/s |
- 12.78x slower |
+ 129,634 op/s |
+ 12.60x slower |
| @xmldom/xmldom |
- 96,510 op/s |
- 17.21x slower |
+ 94,080 op/s |
+ 17.36x slower |
@@ -115,28 +115,28 @@ Parse an XML string into a tree structure.
| Eksml |
- 139,120 op/s |
+ 137,377 op/s |
— |
| htmlparser2 |
- 24,828 op/s |
- 5.60x slower |
+ 24,579 op/s |
+ 5.59x slower |
| fast-xml-parser |
- 9,819 op/s |
- 14.17x slower |
+ 9,813 op/s |
+ 14.00x slower |
| xml2js |
- 9,512 op/s |
- 14.63x slower |
+ 9,296 op/s |
+ 14.78x slower |
| @xmldom/xmldom |
- 6,090 op/s |
- 22.84x slower |
+ 5,808 op/s |
+ 23.65x slower |
@@ -154,33 +154,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 87,674 op/s |
+ 90,320 op/s |
— |
| tXml |
- 48,827 op/s |
- 1.80x slower |
+ 49,642 op/s |
+ 1.82x slower |
| htmlparser2 |
- 17,611 op/s |
- 4.98x slower |
+ 16,901 op/s |
+ 5.34x slower |
- | fast-xml-parser |
- 7,163 op/s |
- 12.24x slower |
+ xml2js |
+ 7,142 op/s |
+ 12.65x slower |
- | xml2js |
- 7,089 op/s |
- 12.37x slower |
+ fast-xml-parser |
+ 7,064 op/s |
+ 12.79x slower |
| @xmldom/xmldom |
- 5,055 op/s |
- 17.34x slower |
+ 4,989 op/s |
+ 18.10x slower |
@@ -198,33 +198,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 52,445 op/s |
+ 52,715 op/s |
— |
| tXml |
- 27,496 op/s |
- 1.91x slower |
+ 26,179 op/s |
+ 2.01x slower |
| htmlparser2 |
- 9,508 op/s |
- 5.52x slower |
+ 9,972 op/s |
+ 5.29x slower |
| xml2js |
- 3,847 op/s |
- 13.63x slower |
+ 3,743 op/s |
+ 14.08x slower |
| fast-xml-parser |
- 3,534 op/s |
- 14.84x slower |
+ 3,649 op/s |
+ 14.45x slower |
| @xmldom/xmldom |
- 2,578 op/s |
- 20.34x slower |
+ 2,563 op/s |
+ 20.56x slower |
@@ -242,33 +242,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 19,591 op/s |
+ 19,899 op/s |
— |
| tXml |
- 11,172 op/s |
- 1.75x slower |
+ 11,174 op/s |
+ 1.78x slower |
| htmlparser2 |
- 3,526 op/s |
- 5.56x slower |
+ 3,421 op/s |
+ 5.82x slower |
| xml2js |
- 1,590 op/s |
- 12.32x slower |
+ 1,603 op/s |
+ 12.41x slower |
| fast-xml-parser |
- 1,275 op/s |
- 15.37x slower |
+ 1,285 op/s |
+ 15.49x slower |
| @xmldom/xmldom |
- 860 op/s |
- 22.77x slower |
+ 882 op/s |
+ 22.57x slower |
@@ -286,33 +286,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 23,252 op/s |
+ 23,438 op/s |
— |
| tXml |
- 13,230 op/s |
- 1.76x slower |
+ 12,804 op/s |
+ 1.83x slower |
| htmlparser2 |
- 4,745 op/s |
- 4.90x slower |
+ 4,901 op/s |
+ 4.78x slower |
| fast-xml-parser |
- 2,198 op/s |
- 10.58x slower |
+ 2,285 op/s |
+ 10.26x slower |
| xml2js |
- 2,056 op/s |
- 11.31x slower |
+ 1,971 op/s |
+ 11.89x slower |
| @xmldom/xmldom |
- 1,405 op/s |
- 16.55x slower |
+ 1,400 op/s |
+ 16.74x slower |
@@ -330,33 +330,33 @@ Parse an XML string into a tree structure.
| Eksml |
- 19,559 op/s |
+ 19,366 op/s |
— |
| tXml |
- 10,764 op/s |
- 1.82x slower |
+ 10,296 op/s |
+ 1.88x slower |
| htmlparser2 |
- 3,938 op/s |
- 4.97x slower |
+ 3,945 op/s |
+ 4.91x slower |
| xml2js |
- 1,498 op/s |
- 13.06x slower |
+ 1,450 op/s |
+ 13.36x slower |
| fast-xml-parser |
- 1,272 op/s |
- 15.38x slower |
+ 1,277 op/s |
+ 15.16x slower |
| @xmldom/xmldom |
- 733 op/s |
- 26.67x slower |
+ 723 op/s |
+ 26.80x slower |
@@ -378,38 +378,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| Eksml (SAX) |
- 21,566 op/s |
+ 21,122 op/s |
— |
| easysax |
- 16,708 op/s |
- 1.29x slower |
+ 16,631 op/s |
+ 1.27x slower |
| @tuananh/sax-parser |
- 15,546 op/s |
- 1.39x slower |
+ 15,037 op/s |
+ 1.40x slower |
| Eksml (XmlParseStream) |
- 10,703 op/s |
- 2.02x slower |
+ 10,840 op/s |
+ 1.95x slower |
| htmlparser2 |
- 8,747 op/s |
- 2.47x slower |
+ 8,653 op/s |
+ 2.44x slower |
| saxes |
- 8,494 op/s |
- 2.54x slower |
+ 8,337 op/s |
+ 2.53x slower |
| sax |
- 4,583 op/s |
- 4.71x slower |
+ 4,568 op/s |
+ 4.62x slower |
@@ -432,38 +432,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| Eksml (SAX) |
- 86,980 op/s |
+ 91,554 op/s |
— |
| easysax |
- 66,925 op/s |
- 1.30x slower |
+ 67,124 op/s |
+ 1.36x slower |
| Eksml (XmlParseStream) |
- 32,998 op/s |
- 2.64x slower |
+ 33,971 op/s |
+ 2.70x slower |
- | saxes |
- 29,356 op/s |
- 2.96x slower |
+ htmlparser2 |
+ 29,824 op/s |
+ 3.07x slower |
- | htmlparser2 |
- 28,528 op/s |
- 3.05x slower |
+ saxes |
+ 29,578 op/s |
+ 3.10x slower |
| @tuananh/sax-parser |
- 23,954 op/s |
- 3.63x slower |
+ 22,979 op/s |
+ 3.98x slower |
| sax |
- 14,792 op/s |
- 5.88x slower |
+ 14,185 op/s |
+ 6.45x slower |
@@ -481,38 +481,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| Eksml (SAX) |
- 16,960 op/s |
+ 17,768 op/s |
— |
| @tuananh/sax-parser |
- 15,829 op/s |
- 1.07x slower |
+ 15,336 op/s |
+ 1.16x slower |
| easysax |
- 14,401 op/s |
- 1.18x slower |
+ 14,474 op/s |
+ 1.23x slower |
| Eksml (XmlParseStream) |
- 10,874 op/s |
- 1.56x slower |
+ 10,759 op/s |
+ 1.65x slower |
| htmlparser2 |
- 7,039 op/s |
- 2.41x slower |
+ 7,155 op/s |
+ 2.48x slower |
| saxes |
- 6,612 op/s |
- 2.57x slower |
+ 6,608 op/s |
+ 2.69x slower |
| sax |
- 3,826 op/s |
- 4.43x slower |
+ 3,868 op/s |
+ 4.59x slower |
@@ -530,38 +530,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| Eksml (SAX) |
- 15,205 op/s |
+ 13,520 op/s |
— |
| @tuananh/sax-parser |
- 13,789 op/s |
- 1.10x slower |
+ 12,466 op/s |
+ 1.08x slower |
| easysax |
- 11,127 op/s |
- 1.37x slower |
+ 11,027 op/s |
+ 1.23x slower |
| Eksml (XmlParseStream) |
- 8,754 op/s |
- 1.74x slower |
+ 9,125 op/s |
+ 1.48x slower |
| saxes |
- 6,692 op/s |
- 2.27x slower |
+ 5,911 op/s |
+ 2.29x slower |
| htmlparser2 |
- 5,647 op/s |
- 2.69x slower |
+ 5,668 op/s |
+ 2.39x slower |
| sax |
- 3,011 op/s |
- 5.05x slower |
+ 3,036 op/s |
+ 4.45x slower |
@@ -579,38 +579,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| @tuananh/sax-parser |
- 15,447 op/s |
+ 15,387 op/s |
— |
| Eksml (SAX) |
- 15,253 op/s |
- 1.01x slower |
+ 14,770 op/s |
+ 1.04x slower |
| easysax |
- 11,398 op/s |
- 1.36x slower |
+ 11,140 op/s |
+ 1.38x slower |
- | htmlparser2 |
- 6,797 op/s |
- 2.27x slower |
+ saxes |
+ 6,256 op/s |
+ 2.46x slower |
- | saxes |
- 6,169 op/s |
- 2.50x slower |
+ htmlparser2 |
+ 6,237 op/s |
+ 2.47x slower |
| Eksml (XmlParseStream) |
- 5,087 op/s |
- 3.04x slower |
+ 5,244 op/s |
+ 2.93x slower |
| sax |
- 3,799 op/s |
- 4.07x slower |
+ 3,797 op/s |
+ 4.05x slower |
@@ -628,38 +628,38 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full
| Eksml (SAX) |
- 13,636 op/s |
+ 12,942 op/s |
— |
| @tuananh/sax-parser |
- 11,243 op/s |
- 1.21x slower |
+ 11,374 op/s |
+ 1.14x slower |
| easysax |
- 10,651 op/s |
- 1.28x slower |
+ 10,659 op/s |
+ 1.21x slower |
| Eksml (XmlParseStream) |
- 8,787 op/s |
- 1.55x slower |
+ 8,559 op/s |
+ 1.51x slower |
| htmlparser2 |
- 6,642 op/s |
- 2.05x slower |
+ 6,429 op/s |
+ 2.01x slower |
| saxes |
- 5,518 op/s |
- 2.47x slower |
+ 5,572 op/s |
+ 2.32x slower |
| sax |
- 3,121 op/s |
- 4.37x slower |
+ 3,146 op/s |
+ 4.11x slower |
@@ -681,33 +681,33 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 27,205 op/s |
+ 26,729 op/s |
— |
| easysax |
- 18,038 op/s |
- 1.51x slower |
+ 18,107 op/s |
+ 1.48x slower |
| @tuananh/sax-parser |
- 16,027 op/s |
+ 15,681 op/s |
1.70x slower |
| saxes |
- 11,093 op/s |
- 2.45x slower |
+ 11,245 op/s |
+ 2.38x slower |
| htmlparser2 |
- 9,308 op/s |
- 2.92x slower |
+ 9,282 op/s |
+ 2.88x slower |
| sax |
- 4,665 op/s |
- 5.83x slower |
+ 4,668 op/s |
+ 5.73x slower |
@@ -730,33 +730,33 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 113,398 op/s |
+ 108,772 op/s |
— |
| easysax |
- 72,718 op/s |
- 1.56x slower |
+ 72,583 op/s |
+ 1.50x slower |
| saxes |
- 34,958 op/s |
- 3.24x slower |
+ 34,658 op/s |
+ 3.14x slower |
| htmlparser2 |
- 28,807 op/s |
- 3.94x slower |
+ 30,335 op/s |
+ 3.59x slower |
| @tuananh/sax-parser |
- 22,715 op/s |
+ 21,781 op/s |
4.99x slower |
| sax |
- 14,575 op/s |
- 7.78x slower |
+ 15,280 op/s |
+ 7.12x slower |
@@ -774,33 +774,33 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 20,910 op/s |
+ 21,111 op/s |
— |
| @tuananh/sax-parser |
- 16,455 op/s |
- 1.27x slower |
+ 16,254 op/s |
+ 1.30x slower |
| easysax |
- 15,663 op/s |
- 1.33x slower |
+ 15,723 op/s |
+ 1.34x slower |
| saxes |
- 9,285 op/s |
+ 9,391 op/s |
2.25x slower |
| htmlparser2 |
- 7,642 op/s |
- 2.74x slower |
+ 7,498 op/s |
+ 2.82x slower |
| sax |
- 3,938 op/s |
- 5.31x slower |
+ 3,765 op/s |
+ 5.61x slower |
@@ -818,32 +818,32 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 19,668 op/s |
+ 19,368 op/s |
— |
| @tuananh/sax-parser |
- 14,481 op/s |
- 1.36x slower |
+ 14,365 op/s |
+ 1.35x slower |
| easysax |
- 12,674 op/s |
- 1.55x slower |
+ 11,967 op/s |
+ 1.62x slower |
| saxes |
- 8,199 op/s |
- 2.40x slower |
+ 7,842 op/s |
+ 2.47x slower |
| htmlparser2 |
- 6,288 op/s |
- 3.13x slower |
+ 6,267 op/s |
+ 3.09x slower |
| sax |
- 3,109 op/s |
+ 3,059 op/s |
6.33x slower |
@@ -862,33 +862,33 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 17,497 op/s |
+ 17,818 op/s |
— |
| @tuananh/sax-parser |
- 15,967 op/s |
- 1.10x slower |
+ 15,297 op/s |
+ 1.16x slower |
| easysax |
- 11,017 op/s |
- 1.59x slower |
+ 11,990 op/s |
+ 1.49x slower |
| saxes |
- 8,085 op/s |
- 2.16x slower |
+ 8,429 op/s |
+ 2.11x slower |
| htmlparser2 |
- 7,079 op/s |
- 2.47x slower |
+ 7,091 op/s |
+ 2.51x slower |
| sax |
- 3,763 op/s |
- 4.65x slower |
+ 3,873 op/s |
+ 4.60x slower |
@@ -906,33 +906,33 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw
| Eksml (SAX) |
- 18,262 op/s |
+ 17,215 op/s |
— |
| @tuananh/sax-parser |
- 12,236 op/s |
- 1.49x slower |
+ 12,186 op/s |
+ 1.41x slower |
| easysax |
- 12,009 op/s |
- 1.52x slower |
+ 11,887 op/s |
+ 1.45x slower |
| saxes |
- 7,808 op/s |
- 2.34x slower |
+ 8,357 op/s |
+ 2.06x slower |
| htmlparser2 |
- 7,128 op/s |
- 2.56x slower |
+ 6,815 op/s |
+ 2.53x slower |
| sax |
- 3,290 op/s |
- 5.55x slower |
+ 3,251 op/s |
+ 5.30x slower |
@@ -952,18 +952,18 @@ Chunked tokenization of a 10 MB document — a seeded, faker-generated product c
| Eksml (SAX) |
- 32.0 op/s |
+ 32.2 op/s |
— |
| easysax |
- 21.7 op/s |
- 1.48x slower |
+ 20.2 op/s |
+ 1.59x slower |
| saxes |
- 12.1 op/s |
- 2.64x slower |
+ 11.6 op/s |
+ 2.77x slower |
| htmlparser2 |
@@ -972,13 +972,13 @@ Chunked tokenization of a 10 MB document — a seeded, faker-generated product c
| @tuananh/sax-parser |
- 8.5 op/s |
- 3.74x slower |
+ 9.0 op/s |
+ 3.56x slower |
| sax |
5.4 op/s |
- 5.94x slower |
+ 6.00x slower |
@@ -1000,38 +1000,38 @@ Serialize a pre-parsed in-memory tree back to XML.
| Eksml (validate: false) |
- 218,385 op/s |
+ 221,461 op/s |
— |
| Eksml |
- 190,592 op/s |
+ 191,821 op/s |
1.15x slower |
| tXml |
- 162,265 op/s |
- 1.35x slower |
+ 160,362 op/s |
+ 1.38x slower |
| htmlparser2 |
- 68,263 op/s |
+ 69,271 op/s |
3.20x slower |
| @xmldom/xmldom |
- 35,335 op/s |
- 6.18x slower |
+ 35,871 op/s |
+ 6.17x slower |
| fast-xml-parser |
- 18,703 op/s |
- 11.68x slower |
+ 18,761 op/s |
+ 11.80x slower |
| xml2js |
- 15,320 op/s |
- 14.25x slower |
+ 14,829 op/s |
+ 14.93x slower |
@@ -1054,38 +1054,38 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 2,595,279 op/s |
+ 2,854,612 op/s |
— |
- | tXml |
- 2,467,524 op/s |
- 1.05x slower |
+ Eksml |
+ 2,520,999 op/s |
+ 1.13x slower |
- | Eksml |
- 2,425,920 op/s |
- 1.07x slower |
+ tXml |
+ 2,464,014 op/s |
+ 1.16x slower |
| htmlparser2 |
- 2,013,627 op/s |
- 1.29x slower |
+ 2,080,986 op/s |
+ 1.37x slower |
| @xmldom/xmldom |
- 1,146,014 op/s |
- 2.26x slower |
+ 1,147,270 op/s |
+ 2.49x slower |
| fast-xml-parser |
- 382,971 op/s |
- 6.78x slower |
+ 380,590 op/s |
+ 7.50x slower |
| xml2js |
- 245,615 op/s |
- 10.57x slower |
+ 247,316 op/s |
+ 11.54x slower |
@@ -1103,33 +1103,33 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 395,563 op/s |
+ 397,794 op/s |
— |
| Eksml |
- 331,671 op/s |
- 1.19x slower |
+ 335,840 op/s |
+ 1.18x slower |
| htmlparser2 |
- 97,145 op/s |
- 4.07x slower |
+ 102,950 op/s |
+ 3.86x slower |
| @xmldom/xmldom |
- 46,099 op/s |
- 8.58x slower |
+ 46,699 op/s |
+ 8.52x slower |
| fast-xml-parser |
- 23,292 op/s |
- 16.98x slower |
+ 23,139 op/s |
+ 17.19x slower |
| xml2js |
- 16,994 op/s |
- 23.28x slower |
+ 16,204 op/s |
+ 24.55x slower |
@@ -1147,38 +1147,38 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 269,993 op/s |
+ 269,207 op/s |
— |
| Eksml |
- 235,359 op/s |
- 1.15x slower |
+ 236,969 op/s |
+ 1.14x slower |
| tXml |
- 232,137 op/s |
+ 232,661 op/s |
1.16x slower |
| htmlparser2 |
- 69,038 op/s |
- 3.91x slower |
+ 73,950 op/s |
+ 3.64x slower |
| @xmldom/xmldom |
- 39,906 op/s |
- 6.77x slower |
+ 38,777 op/s |
+ 6.94x slower |
| fast-xml-parser |
- 27,028 op/s |
- 9.99x slower |
+ 29,285 op/s |
+ 9.19x slower |
| xml2js |
- 19,135 op/s |
- 14.11x slower |
+ 18,159 op/s |
+ 14.82x slower |
@@ -1196,38 +1196,38 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 116,037 op/s |
+ 115,850 op/s |
— |
| Eksml |
- 101,175 op/s |
- 1.15x slower |
+ 99,427 op/s |
+ 1.17x slower |
| tXml |
- 93,107 op/s |
- 1.25x slower |
+ 88,035 op/s |
+ 1.32x slower |
| htmlparser2 |
- 30,473 op/s |
- 3.81x slower |
+ 28,747 op/s |
+ 4.03x slower |
| @xmldom/xmldom |
- 14,260 op/s |
- 8.14x slower |
+ 14,373 op/s |
+ 8.06x slower |
| fast-xml-parser |
- 11,288 op/s |
- 10.28x slower |
+ 11,743 op/s |
+ 9.87x slower |
| xml2js |
- 8,607 op/s |
- 13.48x slower |
+ 8,297 op/s |
+ 13.96x slower |
@@ -1245,38 +1245,38 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 66,775 op/s |
+ 66,135 op/s |
— |
| Eksml |
- 57,227 op/s |
+ 56,458 op/s |
1.17x slower |
| tXml |
- 48,396 op/s |
- 1.38x slower |
+ 48,204 op/s |
+ 1.37x slower |
| htmlparser2 |
- 14,617 op/s |
- 4.57x slower |
+ 14,777 op/s |
+ 4.48x slower |
| @xmldom/xmldom |
- 6,854 op/s |
- 9.74x slower |
+ 7,186 op/s |
+ 9.20x slower |
| fast-xml-parser |
- 4,429 op/s |
- 15.08x slower |
+ 4,641 op/s |
+ 14.25x slower |
| xml2js |
- 4,405 op/s |
- 15.16x slower |
+ 4,124 op/s |
+ 16.04x slower |
@@ -1294,38 +1294,38 @@ With `validate: false`, Eksml leads every fixture (tXml crashes on RSS). With va
| Eksml (validate: false) |
- 50,509 op/s |
+ 50,369 op/s |
— |
| Eksml |
- 43,716 op/s |
- 1.16x slower |
+ 44,234 op/s |
+ 1.14x slower |
| tXml |
- 43,583 op/s |
+ 43,591 op/s |
1.16x slower |
| htmlparser2 |
- 16,821 op/s |
- 3.00x slower |
+ 16,417 op/s |
+ 3.07x slower |
| @xmldom/xmldom |
- 9,445 op/s |
- 5.35x slower |
+ 9,928 op/s |
+ 5.07x slower |
| xml2js |
- 4,270 op/s |
- 11.83x slower |
+ 4,269 op/s |
+ 11.80x slower |
| fast-xml-parser |
- 3,551 op/s |
- 14.22x slower |
+ 3,102 op/s |
+ 16.24x slower |
diff --git a/eksml/package.json b/eksml/package.json
index 544c840..a6dd4da 100644
--- a/eksml/package.json
+++ b/eksml/package.json
@@ -85,7 +85,7 @@
"packageManager": "pnpm@10.33.0",
"devDependencies": {
"@faker-js/faker": "^10.5.0",
- "@tuananh/sax-parser": "^1.6.0",
+ "@tuananh/sax-parser": "^1.7.0",
"@types/node": "^25.5.0",
"@types/sax": "^1.2.7",
"@types/xml2js": "^0.4.14",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e01d09f..6319f80 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -152,8 +152,8 @@ importers:
specifier: ^10.5.0
version: 10.5.0
'@tuananh/sax-parser':
- specifier: ^1.6.0
- version: 1.6.0
+ specifier: ^1.7.0
+ version: 1.7.0
'@types/node':
specifier: ^25.5.0
version: 25.5.0
@@ -1587,60 +1587,60 @@ packages:
resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
engines: {node: '>= 6'}
- '@tuananh/sax-parser-darwin-arm64@1.6.0':
- resolution: {integrity: sha512-ZF1O8TEbduDj8X2zivoGsPjafzcGV8axRgF4j+BpGHaLXyfS8BNSz05apEdqexUJDDCxemiNbOhu6UcKKzXOLg==}
+ '@tuananh/sax-parser-darwin-arm64@1.7.0':
+ resolution: {integrity: sha512-r1vYqmux2b+GLgSBnQMQ8Xc4VZKXXyrqZhCvjwvkEk3XiPxs7N2pDWHAoq4UPgqY5ss2wEk4IvDYJ/3dVBc6GA==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [darwin]
- '@tuananh/sax-parser-darwin-x64@1.6.0':
- resolution: {integrity: sha512-c1PsZrxADUtXZ0Zfx9OJsILmWLmG/VGY0IoVW92eiDUetwtmheg9XsKmahHHDSw0lOdVBNa2Dkx+yQboEh5rEQ==}
+ '@tuananh/sax-parser-darwin-x64@1.7.0':
+ resolution: {integrity: sha512-EK9mJPpvKv3gURXIHEIF/RBjVaoTF7p5O0yh305TP7YHNwbpWmUQQgw4XksNRNjO9UWZlLleHrdaCXKyaxYyvw==}
engines: {node: '>= 18'}
cpu: [x64]
os: [darwin]
- '@tuananh/sax-parser-linux-arm64-gnu@1.6.0':
- resolution: {integrity: sha512-mDG5ty3HOl8qUrYfN/NSPLb6/9a0Aj6CLlWwW5VTwtAmSgFtbg9Xa1twhZsAS7ypK8ysdSDFkSH5fwS7/vxCng==}
+ '@tuananh/sax-parser-linux-arm64-gnu@1.7.0':
+ resolution: {integrity: sha512-I/fOKjaiXF8vgBx+nNJfPdhMq4jKulL8Mh45noTt4km2iKTDP3dI3ZIIkNMrKFA4ySld0xecVjKfLP5JcOnaFA==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [linux]
libc: [glibc]
- '@tuananh/sax-parser-linux-arm64-musl@1.6.0':
- resolution: {integrity: sha512-pci78rOkH7cC4Y1vILyt/iyA6lYXyYzpXqLZMJOCZbbaArva1i96+/duu17cMphdeJw/Unmx5j1Zt4umJ/SolA==}
+ '@tuananh/sax-parser-linux-arm64-musl@1.7.0':
+ resolution: {integrity: sha512-WYdw0aKX8x4yWuEt95eCsQW3vSCD27JQ6NFD8Mmfw+bUw6rR2bzmMxhsAXwckUOojefwKEuxKxr8OSScxYBa/w==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [linux]
libc: [musl]
- '@tuananh/sax-parser-linux-x64-gnu@1.6.0':
- resolution: {integrity: sha512-beB0khG2FKCT6uF7zSpsJgBdndRtRHpB+wfPdJJZwmTKy5PsR5tx0vP9L+fNVheOtHqo4P/SqC0MQcF06wkTeg==}
+ '@tuananh/sax-parser-linux-x64-gnu@1.7.0':
+ resolution: {integrity: sha512-2XPWltnLSJ/U3uif2AORCn/sT/zx5q0BLrXyBUuzIDZufKQirTtS2YP0LPn57+I0R788xWZX+78+mccL70B2AA==}
engines: {node: '>= 18'}
cpu: [x64]
os: [linux]
libc: [glibc]
- '@tuananh/sax-parser-linux-x64-musl@1.6.0':
- resolution: {integrity: sha512-+/Bo1Z4oCwq/dpetZT5KopQAetLwQp4TWj+dPuiP/ZOG+y9+k+30wD5Emra0XqMF7D+ZVXHUynZmsAgcD1XCUA==}
+ '@tuananh/sax-parser-linux-x64-musl@1.7.0':
+ resolution: {integrity: sha512-dKSuqFN60zKSycWBVbAbsfTCl8dcvl5hSCX2cVhq2sD1OM6jcohw9r5SKFVKcitF2oc0PFWCKaRaRZ0P9H5kRg==}
engines: {node: '>= 18'}
cpu: [x64]
os: [linux]
libc: [musl]
- '@tuananh/sax-parser-win32-arm64-msvc@1.6.0':
- resolution: {integrity: sha512-UesR/sqEesf07jftFR6dSSYUUV8obRCfOuIssSWdKUF7iw+q44NvwIQ4q4gyEQru3UU1KvOGc5LlWkH86mYX3Q==}
+ '@tuananh/sax-parser-win32-arm64-msvc@1.7.0':
+ resolution: {integrity: sha512-3+vY3nQRVP/WM1nld1O5S6g4R/fcuAw3Ik8ZLwy8irfyWfa+Y/TlLe7ODibqJ/0bUdZZPBiBQiYr4e+EBogEgw==}
engines: {node: '>= 18'}
cpu: [arm64]
os: [win32]
- '@tuananh/sax-parser-win32-x64-msvc@1.6.0':
- resolution: {integrity: sha512-uI/x2jTs55IgOvnvp519DIglRoVaA73+KW8O34fmZzqm3/7MPLmtsid6r7RiS8yNnwSNJJhCgbbUIyJZBqkAww==}
+ '@tuananh/sax-parser-win32-x64-msvc@1.7.0':
+ resolution: {integrity: sha512-RNeS/sYOgyXH/DTo2hccX9CxxYubnI2HvnkFqv5Kwz92gEiP5dIRKCfYcECkXbfeloDrhibn6xtcBzUA761AKA==}
engines: {node: '>= 18'}
cpu: [x64]
os: [win32]
- '@tuananh/sax-parser@1.6.0':
- resolution: {integrity: sha512-tgWlt+a0GyKO8HA6oOmf6YGrdJkLTFlcNS/hE6pE53WtweNNU9hJKcBVn2iXkF/V4RHuOFR90ZvsSPuV5A8akg==}
+ '@tuananh/sax-parser@1.7.0':
+ resolution: {integrity: sha512-GSsYyThD9E8YfdkAI8GC0Fo3jFP05e46KGYT4EANqmFKyPpfgCuZ5zUywTKx7IA0dbuDTYHOONp57TFF60Fcsg==}
engines: {node: '>= 18'}
'@tybys/wasm-util@0.10.1':
@@ -6757,44 +6757,44 @@ snapshots:
'@tootallnate/once@1.1.2': {}
- '@tuananh/sax-parser-darwin-arm64@1.6.0':
+ '@tuananh/sax-parser-darwin-arm64@1.7.0':
optional: true
- '@tuananh/sax-parser-darwin-x64@1.6.0':
+ '@tuananh/sax-parser-darwin-x64@1.7.0':
optional: true
- '@tuananh/sax-parser-linux-arm64-gnu@1.6.0':
+ '@tuananh/sax-parser-linux-arm64-gnu@1.7.0':
optional: true
- '@tuananh/sax-parser-linux-arm64-musl@1.6.0':
+ '@tuananh/sax-parser-linux-arm64-musl@1.7.0':
optional: true
- '@tuananh/sax-parser-linux-x64-gnu@1.6.0':
+ '@tuananh/sax-parser-linux-x64-gnu@1.7.0':
optional: true
- '@tuananh/sax-parser-linux-x64-musl@1.6.0':
+ '@tuananh/sax-parser-linux-x64-musl@1.7.0':
optional: true
- '@tuananh/sax-parser-win32-arm64-msvc@1.6.0':
+ '@tuananh/sax-parser-win32-arm64-msvc@1.7.0':
optional: true
- '@tuananh/sax-parser-win32-x64-msvc@1.6.0':
+ '@tuananh/sax-parser-win32-x64-msvc@1.7.0':
optional: true
- '@tuananh/sax-parser@1.6.0':
+ '@tuananh/sax-parser@1.7.0':
dependencies:
bindings: 1.5.0
detect-libc: 2.1.2
node-addon-api: 8.9.0
optionalDependencies:
- '@tuananh/sax-parser-darwin-arm64': 1.6.0
- '@tuananh/sax-parser-darwin-x64': 1.6.0
- '@tuananh/sax-parser-linux-arm64-gnu': 1.6.0
- '@tuananh/sax-parser-linux-arm64-musl': 1.6.0
- '@tuananh/sax-parser-linux-x64-gnu': 1.6.0
- '@tuananh/sax-parser-linux-x64-musl': 1.6.0
- '@tuananh/sax-parser-win32-arm64-msvc': 1.6.0
- '@tuananh/sax-parser-win32-x64-msvc': 1.6.0
+ '@tuananh/sax-parser-darwin-arm64': 1.7.0
+ '@tuananh/sax-parser-darwin-x64': 1.7.0
+ '@tuananh/sax-parser-linux-arm64-gnu': 1.7.0
+ '@tuananh/sax-parser-linux-arm64-musl': 1.7.0
+ '@tuananh/sax-parser-linux-x64-gnu': 1.7.0
+ '@tuananh/sax-parser-linux-x64-musl': 1.7.0
+ '@tuananh/sax-parser-win32-arm64-msvc': 1.7.0
+ '@tuananh/sax-parser-win32-x64-msvc': 1.7.0
'@tybys/wasm-util@0.10.1':
dependencies: