diff --git a/benchmark.json b/benchmark.json index 4d70f0ab..7d8e2223 100644 --- a/benchmark.json +++ b/benchmark.json @@ -1,11 +1,18 @@ { "evalConfig": { "tolerance": { - "*": [0.75, 1.5] + "*": [0.75, 1.5], + "*.dev": [0.01, 1.5], + "*.cv": [0.01, 1.5], + "EscapeSequenceParser.benchmark.js.*.averageThroughput.mean": [0.9, 5] }, "skip": [ "*.median", - "*.runs" + "*.runs", + "*.dev", + "*.cv", + "EscapeSequenceParser.benchmark.js.*.averageRuntime", + "Terminal.benchmark.js.*.averageRuntime" ] } -} \ No newline at end of file +} diff --git a/bin/benchmark.js b/bin/benchmark.js index a03f6e16..894d98db 100644 --- a/bin/benchmark.js +++ b/bin/benchmark.js @@ -19,8 +19,8 @@ env.NODE_PATH = path.resolve(__dirname, '../out'); */ const commands = { single : '-c benchmark.json', - baseline: '--baseline -r 10 -c benchmark.json', - eval : '--eval -r 10 -c benchmark.json' + baseline: '--baseline -r 5 -c benchmark.json', + eval : '--eval -r 5 -c benchmark.json' } let testFiles = [ diff --git a/src/Terminal.benchmark.ts b/src/Terminal.benchmark.ts new file mode 100644 index 00000000..fafd85cf --- /dev/null +++ b/src/Terminal.benchmark.ts @@ -0,0 +1,75 @@ +import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; + +import { Terminal } from 'Terminal'; +import { spawn } from 'node-pty'; +import { Utf8ToUtf32, stringFromCodePoint } from '../out/core/input/TextDecoder'; + + +class TestTerminal extends Terminal { + writeSync(data: string): void { + this.writeBuffer.push(data); + this._innerWrite(); + } + writeSyncUtf8(data: Uint8Array): void { + this.writeBufferUtf8.push(data); + this._innerWriteUtf8(); + } +} + +perfContext('Terminal: ls -lR /usr', () => { + let content = ''; + let contentUtf8: Uint8Array; + + before(async () => { + // grab output from "ls -lR /usr" + const p = spawn('ls', ['--color=auto', '-lR', '/usr'], { + name: 'xterm-color', + cols: 80, + rows: 25, + cwd: process.env.HOME, + env: process.env, + encoding: null + }); + const chunks: Buffer[] = []; + let length = 0; + p.on('data', data => { + chunks.push(data as unknown as Buffer); + length += data.length; + }); + await new Promise(resolve => p.on('exit', () => resolve())); + contentUtf8 = Buffer.concat(chunks, length); + // translate to content string + const buffer = new Uint32Array(contentUtf8.length); + const decoder = new Utf8ToUtf32(); + const codepoints = decoder.decode(contentUtf8, buffer); + for (let i = 0; i < codepoints; ++i) { + content += stringFromCodePoint(buffer[i]); + // peek into content to force flat repr in v8 + if (!(i % 10000000)) { + content[i]; + } + } + }); + + perfContext('write', () => { + let terminal: TestTerminal; + before(() => { + terminal = new TestTerminal({cols: 80, rows: 25, scrollback: 1000}); + }); + new ThroughputRuntimeCase('', () => { + terminal.writeSync(content); + return {payloadSize: contentUtf8.length}; + }, {fork: false}).showAverageThroughput(); + }); + + perfContext('writeUtf8', () => { + let terminal: TestTerminal; + before(() => { + terminal = new TestTerminal({cols: 80, rows: 25, scrollback: 1000}); + }); + new ThroughputRuntimeCase('', () => { + terminal.writeSyncUtf8(contentUtf8); + return {payloadSize: contentUtf8.length}; + }, {fork: false}).showAverageThroughput(); + }); +});