mirror of
https://github.com/markedjs/marked
synced 2024-11-23 09:48:17 +00:00
add bench.json
This commit is contained in:
parent
c99e69b406
commit
99d1fd00e0
@ -58,7 +58,7 @@
|
||||
"test:lint": "eslint bin/marked .",
|
||||
"test:redos": "eslint --plugin vuln-regex-detector --rule '\"vuln-regex-detector/no-vuln-regex\": 2' lib/marked.js",
|
||||
"test:node4": "npx node@4 ./node_modules/jasmine/bin/jasmine.js --config=jasmine.json",
|
||||
"bench": "node test --bench",
|
||||
"bench": "node test/bench.js",
|
||||
"lint": "eslint --fix bin/marked .",
|
||||
"build": "uglifyjs lib/marked.js -cm --comments /Copyright/ -o marked.min.js",
|
||||
"preversion": "npm run build && (git diff --quiet || git commit -am 'minify')"
|
||||
|
261
test/bench.js
vendored
Normal file
261
test/bench.js
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const htmlDiffer = require('./helpers/html-differ.js');
|
||||
|
||||
let marked = require('../');
|
||||
|
||||
function load() {
|
||||
let folder = path.resolve(__dirname, './specs/commonmark');
|
||||
const files = fs.readdirSync(folder);
|
||||
return files.reduce((arr, file) => {
|
||||
if (file.match(/\.json$/)) {
|
||||
return arr.concat(require(`${folder}/${file}`));
|
||||
}
|
||||
return arr;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function runBench(options) {
|
||||
options = options || {};
|
||||
const specs = load();
|
||||
|
||||
// Non-GFM, Non-pedantic
|
||||
marked.setOptions({
|
||||
gfm: false,
|
||||
tables: false,
|
||||
breaks: false,
|
||||
pedantic: false,
|
||||
sanitize: false,
|
||||
smartLists: false
|
||||
});
|
||||
if (options.marked) {
|
||||
marked.setOptions(options.marked);
|
||||
}
|
||||
bench('marked', specs, marked);
|
||||
|
||||
// GFM
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
tables: false,
|
||||
breaks: false,
|
||||
pedantic: false,
|
||||
sanitize: false,
|
||||
smartLists: false
|
||||
});
|
||||
if (options.marked) {
|
||||
marked.setOptions(options.marked);
|
||||
}
|
||||
bench('marked (gfm)', specs, marked);
|
||||
|
||||
// Pedantic
|
||||
marked.setOptions({
|
||||
gfm: false,
|
||||
tables: false,
|
||||
breaks: false,
|
||||
pedantic: true,
|
||||
sanitize: false,
|
||||
smartLists: false
|
||||
});
|
||||
if (options.marked) {
|
||||
marked.setOptions(options.marked);
|
||||
}
|
||||
bench('marked (pedantic)', specs, marked);
|
||||
|
||||
try {
|
||||
bench('commonmark', specs, (() => {
|
||||
const commonmark = require('commonmark');
|
||||
const parser = new commonmark.Parser();
|
||||
const writer = new commonmark.HtmlRenderer();
|
||||
return function (text) {
|
||||
return writer.render(parser.parse(text));
|
||||
};
|
||||
})());
|
||||
} catch (e) {
|
||||
console.error('Could not bench commonmark. (Error: %s)', e.message);
|
||||
}
|
||||
|
||||
try {
|
||||
bench('markdown-it', specs, (() => {
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const md = new MarkdownIt();
|
||||
return md.render.bind(md);
|
||||
})());
|
||||
} catch (e) {
|
||||
console.error('Could not bench markdown-it. (Error: %s)', e.message);
|
||||
}
|
||||
|
||||
try {
|
||||
bench('markdown.js', specs, (() => {
|
||||
const md = require('markdown').markdown;
|
||||
return md.toHTML.bind(md);
|
||||
})());
|
||||
} catch (e) {
|
||||
console.error('Could not bench markdown.js. (Error: %s)', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function bench(name, specs, engine) {
|
||||
const before = process.hrtime();
|
||||
for (let i = 0; i < 1e3; i++) {
|
||||
for (const spec of specs) {
|
||||
engine(spec.markdown);
|
||||
}
|
||||
}
|
||||
const elapsed = process.hrtime(before);
|
||||
const ms = prettyElapsedTime(elapsed).toFixed();
|
||||
|
||||
const results = [];
|
||||
for (const spec of specs) {
|
||||
results.push({
|
||||
expected: spec.html,
|
||||
actual: engine(spec.markdown)
|
||||
});
|
||||
}
|
||||
const correct = results.reduce((num, result) => num + (htmlDiffer.isEqual(result.expected, result.actual) ? 1 : 0), 0);
|
||||
const percent = (correct / results.length * 100).toFixed(2);
|
||||
|
||||
console.log('%s completed in %sms and passed %s%', name, ms, percent);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple one-time benchmark
|
||||
*/
|
||||
function time(options) {
|
||||
options = options || {};
|
||||
const specs = load();
|
||||
if (options.marked) {
|
||||
marked.setOptions(options.marked);
|
||||
}
|
||||
bench('marked', specs, marked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Argument Parsing
|
||||
*/
|
||||
function parseArg(argv) {
|
||||
argv = argv.slice(2);
|
||||
|
||||
const options = {};
|
||||
const orphans = [];
|
||||
|
||||
function getarg() {
|
||||
let arg = argv.shift();
|
||||
|
||||
if (arg.indexOf('--') === 0) {
|
||||
// e.g. --opt
|
||||
arg = arg.split('=');
|
||||
if (arg.length > 1) {
|
||||
// e.g. --opt=val
|
||||
argv.unshift(arg.slice(1).join('='));
|
||||
}
|
||||
arg = arg[0];
|
||||
} else if (arg[0] === '-') {
|
||||
if (arg.length > 2) {
|
||||
// e.g. -abc
|
||||
argv = arg.substring(1).split('').map(ch => {
|
||||
return `-${ch}`;
|
||||
}).concat(argv);
|
||||
arg = argv.shift();
|
||||
} else {
|
||||
// e.g. -a
|
||||
}
|
||||
} else {
|
||||
// e.g. foo
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
const defaults = marked.getDefaults();
|
||||
|
||||
while (argv.length) {
|
||||
let arg = getarg();
|
||||
switch (arg) {
|
||||
case '-t':
|
||||
case '--time':
|
||||
options.time = true;
|
||||
break;
|
||||
case '-m':
|
||||
case '--minified':
|
||||
options.minified = true;
|
||||
break;
|
||||
default:
|
||||
if (arg.indexOf('--') === 0) {
|
||||
const opt = camelize(arg.replace(/^--(no-)?/, ''));
|
||||
if (!defaults.hasOwnProperty(opt)) {
|
||||
continue;
|
||||
}
|
||||
options.marked = options.marked || {};
|
||||
if (arg.indexOf('--no-') === 0) {
|
||||
options.marked[opt] = typeof defaults[opt] !== 'boolean'
|
||||
? null
|
||||
: false;
|
||||
} else {
|
||||
options.marked[opt] = typeof defaults[opt] !== 'boolean'
|
||||
? argv.shift()
|
||||
: true;
|
||||
}
|
||||
} else {
|
||||
orphans.push(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (orphans.length > 0) {
|
||||
console.error();
|
||||
console.error('The following arguments are not used:');
|
||||
orphans.forEach(arg => console.error(` ${arg}`));
|
||||
console.error();
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
function camelize(text) {
|
||||
return text.replace(/(\w)-(\w)/g, (_, a, b) => a + b.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
function main(argv) {
|
||||
const opt = parseArg(argv);
|
||||
|
||||
if (opt.minified) {
|
||||
marked = require('../marked.min.js');
|
||||
}
|
||||
|
||||
if (opt.time) {
|
||||
time(opt);
|
||||
} else {
|
||||
runBench(opt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns time to millisecond granularity
|
||||
*/
|
||||
function prettyElapsedTime(hrtimeElapsed) {
|
||||
const seconds = hrtimeElapsed[0];
|
||||
const frac = Math.round(hrtimeElapsed[1] / 1e3) / 1e3;
|
||||
return seconds * 1e3 + frac;
|
||||
}
|
||||
|
||||
if (!module.parent) {
|
||||
process.title = 'marked bench';
|
||||
main(process.argv.slice());
|
||||
} else {
|
||||
exports = main;
|
||||
exports.main = main;
|
||||
exports.time = time;
|
||||
exports.runBench = runBench;
|
||||
exports.load = load;
|
||||
exports.bench = bench;
|
||||
module.exports = exports;
|
||||
}
|
Loading…
Reference in New Issue
Block a user