UNPKG

thenavisapp

Version:

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

137 lines (114 loc) 4.71 kB
import { readFileSync, createReadStream, readdirSync } from 'node:fs'; import Benchmark from 'benchmark'; import { loadTreeConstructionTestData } from 'parse5-test-utils/dist/generate-parsing-tests.js'; import { loadSAXParserTestData } from 'parse5-test-utils/dist/load-sax-parser-test-data.js'; import { treeAdapters, WritableStreamStub, finished } from 'parse5-test-utils/dist/common.js'; import * as parse5 from '../../packages/parse5/dist/index.js'; import { ParserStream as parse5Stream } from '../../packages/parse5-parser-stream/dist/index.js'; import * as parse5Upstream from 'parse5'; const hugePagePath = new URL('../../test/data/huge-page/huge-page.html', import.meta.url); const treeConstructionPath = new URL('../../test/data/html5lib-tests/tree-construction', import.meta.url); const saxPath = new URL('../../test/data/sax/', import.meta.url); //HACK: https://github.com/bestiejs/benchmark.js/issues/51 /* global workingCopy, WorkingCopyParserStream, upstreamParser, hugePage, microTests, runMicro, runPages, files */ global.workingCopy = parse5; global.WorkingCopyParserStream = parse5Stream; global.upstreamParser = parse5Upstream; // Huge page data global.hugePage = readFileSync(hugePagePath).toString(); // Micro data global.microTests = loadTreeConstructionTestData(treeConstructionPath, treeAdapters.default) .filter( (test) => //NOTE: this test caused a stack overflow in parse5 v1.x test.input !== '<button><p><button>', ) .map((test) => ({ html: test.input, fragmentContext: test.fragmentContext, })); global.runMicro = function (parser) { for (const test of microTests) { if (test.fragmentContext) { parser.parseFragment(test.fragmentContext, test.html); } else { parser.parse(test.html); } } }; // Pages data const pages = loadSAXParserTestData().map((test) => test.src); global.runPages = function (parser) { for (const page of pages) { parser.parse(page); } }; // Stream data global.files = readdirSync(saxPath).map((dirName) => new URL(`${dirName}/src.html`, saxPath).pathname); // Utils function getHz(suite, testName) { for (let i = 0; i < suite.length; i++) { if (suite[i].name === testName) { return suite[i].hz; } } } function runBench({ name, workingCopyFn, upstreamFn, defer = false }) { const suite = new Benchmark.Suite(name); suite .add('Working copy', workingCopyFn, { defer }) .add('Upstream', upstreamFn, { defer }) .on('start', () => console.log(name)) .on('cycle', (event) => console.log(String(event.target))) .on('complete', () => { const workingCopyHz = getHz(suite, 'Working copy'); const upstreamHz = getHz(suite, 'Upstream'); if (workingCopyHz > upstreamHz) { console.log(`Working copy is ${(workingCopyHz / upstreamHz).toFixed(2)}x faster.\n`); } else { console.log(`Working copy is ${(upstreamHz / workingCopyHz).toFixed(2)}x slower.\n`); } }) .run(); } // Benchmarks runBench({ name: 'parse5 regression benchmark - MICRO', workingCopyFn: () => runMicro(workingCopy), upstreamFn: () => runMicro(upstreamParser), }); runBench({ name: 'parse5 regression benchmark - HUGE', workingCopyFn: () => workingCopy.parse(hugePage), upstreamFn: () => upstreamParser.parse(hugePage), }); runBench({ name: 'parse5 regression benchmark - PAGES', workingCopyFn: () => runPages(workingCopy), upstreamFn: () => runPages(upstreamParser), }); runBench({ name: 'parse5 regression benchmark - STREAM', defer: true, workingCopyFn: async (deferred) => { const parsePromises = files.map((fileName) => { const stream = createReadStream(fileName, 'utf8'); const parserStream = new WorkingCopyParserStream(); stream.pipe(parserStream); return finished(parserStream); }); await Promise.all(parsePromises); deferred.resolve(); }, upstreamFn: async (deferred) => { const parsePromises = files.map(async (fileName) => { const stream = createReadStream(fileName, 'utf8'); const writable = new WritableStreamStub(); stream.pipe(writable); await finished(writable); upstreamParser.parse(writable.writtenData); }); await Promise.all(parsePromises); deferred.resolve(); }, });