126 lines
4.5 KiB
JavaScript
126 lines
4.5 KiB
JavaScript
'use strict';
|
|
|
|
// xterm.js EscapeSequenceParser throughput benchmark
|
|
// Runs against compiled output in out-esbuild/
|
|
// Measures weighted MB/s across representative terminal workloads
|
|
|
|
process.env.NODE_PATH = require('path').resolve(__dirname, '../out-esbuild');
|
|
require('module').Module._initPaths();
|
|
|
|
var EscapeSequenceParser = require('common/parser/EscapeSequenceParser').EscapeSequenceParser;
|
|
var C0 = require('common/data/EscapeSequences').C0;
|
|
|
|
function toUtf32(s) {
|
|
var result = new Uint32Array(s.length);
|
|
for (var i = 0; i < s.length; i++) {
|
|
result[i] = s.charCodeAt(i);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function makeParser() {
|
|
var parser = new EscapeSequenceParser();
|
|
parser.setPrintHandler(function() {});
|
|
parser.setExecuteHandler(C0.LF, function() {});
|
|
parser.setExecuteHandler(C0.CR, function() {});
|
|
parser.setExecuteHandler('\t', function() {});
|
|
parser.setExecuteHandler('\b', function() {});
|
|
parser.registerCsiHandler({ final: 'm' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'H' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'J' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'K' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'A' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'B' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'C' }, function() { return true; });
|
|
parser.registerCsiHandler({ final: 'D' }, function() { return true; });
|
|
parser.registerEscHandler({ final: '7' }, function() { return true; });
|
|
parser.registerEscHandler({ final: '8' }, function() { return true; });
|
|
return parser;
|
|
}
|
|
|
|
var SIZE = 2000000;
|
|
|
|
var cases = [
|
|
['print_ascii', (function() {
|
|
var s = 'The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs.\n';
|
|
var content = '';
|
|
while (content.length < SIZE) content += s;
|
|
return toUtf32(content);
|
|
})(), 4],
|
|
|
|
['sgr_heavy', (function() {
|
|
var s = '\x1b[0;32mfile.txt\x1b[0m \x1b[0;34mdir/\x1b[0m \x1b[1;31merror.log\x1b[0m\n';
|
|
var content = '';
|
|
while (content.length < SIZE) content += s;
|
|
return toUtf32(content);
|
|
})(), 4],
|
|
|
|
['cursor_move', (function() {
|
|
var s = '\x1b[1;1H\x1b[2JStatus: OK\x1b[2;1HLine 2 content here\x1b[3;1HAnother line\n';
|
|
var content = '';
|
|
while (content.length < SIZE) content += s;
|
|
return toUtf32(content);
|
|
})(), 2],
|
|
|
|
['params_heavy', (function() {
|
|
var s = '\x1b[38;5;196mred\x1b[0m \x1b[38;2;0;255;128mgreen\x1b[0m \x1b[48;5;21mblue_bg\x1b[0m\n';
|
|
var content = '';
|
|
while (content.length < SIZE) content += s;
|
|
return toUtf32(content);
|
|
})(), 3],
|
|
|
|
['mixed_realistic', (function() {
|
|
var lines = [
|
|
'\x1b[33mabcd123\x1b[0m fix: resolve parser edge case\n',
|
|
'\x1b[33mef45678\x1b[0m feat: add new feature\n',
|
|
'\x1b[33m9abc012\x1b[0m \x1b[1;31m(HEAD -> main)\x1b[0m chore: update deps\n',
|
|
'\x1b[33m3def456\x1b[0m docs: update readme\n',
|
|
'\x1b[33m789abcd\x1b[0m refactor: clean up utils\n',
|
|
];
|
|
var content = '';
|
|
while (content.length < SIZE) {
|
|
for (var j = 0; j < lines.length; j++) content += lines[j];
|
|
}
|
|
return toUtf32(content);
|
|
})(), 4],
|
|
];
|
|
|
|
function benchOne(parser, data) {
|
|
for (var w = 0; w < 5; w++) parser.parse(data, data.length);
|
|
var runs = [];
|
|
for (var r = 0; r < 7; r++) {
|
|
var t0 = process.hrtime.bigint();
|
|
parser.parse(data, data.length);
|
|
var dt = Number(process.hrtime.bigint() - t0) / 1e9;
|
|
var mbps = (data.length * 4) / (1024 * 1024) / dt;
|
|
runs.push(mbps);
|
|
}
|
|
runs.sort(function(a, b) { return a - b; });
|
|
return runs[Math.floor(runs.length / 2)];
|
|
}
|
|
|
|
var parser = makeParser();
|
|
var totalWeight = 0;
|
|
var weightedSum = 0;
|
|
var perCase = [];
|
|
|
|
for (var c = 0; c < cases.length; c++) {
|
|
var name = cases[c][0];
|
|
var data = cases[c][1];
|
|
var weight = cases[c][2];
|
|
var mbps = benchOne(parser, data);
|
|
perCase.push([name, mbps]);
|
|
weightedSum += mbps * weight;
|
|
totalWeight += weight;
|
|
}
|
|
|
|
var weighted = weightedSum / totalWeight;
|
|
|
|
process.stderr.write('per-case MB/s:\n');
|
|
for (var p = 0; p < perCase.length; p++) {
|
|
process.stderr.write(' ' + perCase[p][0] + ': ' + perCase[p][1].toFixed(1) + '\n');
|
|
}
|
|
process.stderr.write('weighted: ' + weighted.toFixed(1) + ' MB/s\n');
|
|
|
|
process.stdout.write(weighted.toFixed(1) + '\n');
|