moving benchmarks out of './src':
Harder than I thought for several reasons: - need access to common to tests the subparts, thus the unified tsconfig in tests does not work (need the path translation to those parts) - moving next to src I cannot use direct imports anymore (source files are out of rootDir), thus have to rely on d.ts files in out which is quite suboptimal as many parts do not expose the declaration files (can only type Terminal as any atm) - compiler output has to resemble the '../out/..' import logic of the TS files or require fails, thus moved the ouput to './benchmark' for now Conclusion: Not yet there, maybe not a good idea at all to move those tests out of './src' as they heavily rely on not exported internals. Needs more fiddling with the repo structure.
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { Terminal } from 'Terminal';
|
||||
import { spawn } from 'node-pty';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from '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-256color',
|
||||
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();
|
||||
});
|
||||
});
|
||||
@@ -1,266 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { EscapeSequenceParser } from 'core/parser/EscapeSequenceParser';
|
||||
import { C0, C1 } from 'common/data/EscapeSequences';
|
||||
import { IDcsHandler } from './Types';
|
||||
|
||||
|
||||
function toUtf32(s: string): Uint32Array {
|
||||
const result = new Uint32Array(s.length);
|
||||
for (let i = 0; i < s.length; ++i) {
|
||||
result[i] = s.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
perfContext('Parser performance - 50MB data', () => {
|
||||
let content;
|
||||
let taContent: Uint32Array;
|
||||
let parser: EscapeSequenceParser;
|
||||
const dcsHandler: IDcsHandler = {
|
||||
hook: (collect, params, flag) => {},
|
||||
put: (data, start, end) => {},
|
||||
unhook: () => {}
|
||||
};
|
||||
beforeEach(() => {
|
||||
parser = new EscapeSequenceParser();
|
||||
parser.setPrintHandler((data, start, end) => {});
|
||||
parser.setCsiHandler('@', (params, collect) => {});
|
||||
parser.setCsiHandler('A', (params, collect) => {});
|
||||
parser.setCsiHandler('B', (params, collect) => {});
|
||||
parser.setCsiHandler('C', (params, collect) => {});
|
||||
parser.setCsiHandler('D', (params, collect) => {});
|
||||
parser.setCsiHandler('E', (params, collect) => {});
|
||||
parser.setCsiHandler('F', (params, collect) => {});
|
||||
parser.setCsiHandler('G', (params, collect) => {});
|
||||
parser.setCsiHandler('H', (params, collect) => {});
|
||||
parser.setCsiHandler('I', (params, collect) => {});
|
||||
parser.setCsiHandler('J', (params, collect) => {});
|
||||
parser.setCsiHandler('K', (params, collect) => {});
|
||||
parser.setCsiHandler('L', (params, collect) => {});
|
||||
parser.setCsiHandler('M', (params, collect) => {});
|
||||
parser.setCsiHandler('P', (params, collect) => {});
|
||||
parser.setCsiHandler('S', (params, collect) => {});
|
||||
parser.setCsiHandler('T', (params, collect) => {});
|
||||
parser.setCsiHandler('X', (params, collect) => {});
|
||||
parser.setCsiHandler('Z', (params, collect) => {});
|
||||
parser.setCsiHandler('`', (params, collect) => {});
|
||||
parser.setCsiHandler('a', (params, collect) => {});
|
||||
parser.setCsiHandler('b', (params, collect) => {});
|
||||
parser.setCsiHandler('c', (params, collect) => {});
|
||||
parser.setCsiHandler('d', (params, collect) => {});
|
||||
parser.setCsiHandler('e', (params, collect) => {});
|
||||
parser.setCsiHandler('f', (params, collect) => {});
|
||||
parser.setCsiHandler('g', (params, collect) => {});
|
||||
parser.setCsiHandler('h', (params, collect) => {});
|
||||
parser.setCsiHandler('l', (params, collect) => {});
|
||||
parser.setCsiHandler('m', (params, collect) => {});
|
||||
parser.setCsiHandler('n', (params, collect) => {});
|
||||
parser.setCsiHandler('p', (params, collect) => {});
|
||||
parser.setCsiHandler('q', (params, collect) => {});
|
||||
parser.setCsiHandler('r', (params, collect) => {});
|
||||
parser.setCsiHandler('s', (params, collect) => {});
|
||||
parser.setCsiHandler('u', (params, collect) => {});
|
||||
parser.setExecuteHandler(C0.BEL, () => {});
|
||||
parser.setExecuteHandler(C0.LF, () => {});
|
||||
parser.setExecuteHandler(C0.VT, () => {});
|
||||
parser.setExecuteHandler(C0.FF, () => {});
|
||||
parser.setExecuteHandler(C0.CR, () => {});
|
||||
parser.setExecuteHandler(C0.BS, () => {});
|
||||
parser.setExecuteHandler(C0.HT, () => {});
|
||||
parser.setExecuteHandler(C0.SO, () => {});
|
||||
parser.setExecuteHandler(C0.SI, () => {});
|
||||
parser.setExecuteHandler(C1.IND, () => {});
|
||||
parser.setExecuteHandler(C1.NEL, () => {});
|
||||
parser.setExecuteHandler(C1.HTS, () => {});
|
||||
parser.setOscHandler(0, (data) => {});
|
||||
parser.setOscHandler(2, (data) => {});
|
||||
parser.setEscHandler('7', () => {});
|
||||
parser.setEscHandler('8', () => {});
|
||||
parser.setEscHandler('D', () => {});
|
||||
parser.setEscHandler('E', () => {});
|
||||
parser.setEscHandler('H', () => {});
|
||||
parser.setEscHandler('M', () => {});
|
||||
parser.setEscHandler('=', () => {});
|
||||
parser.setEscHandler('>', () => {});
|
||||
parser.setEscHandler('c', () => {});
|
||||
parser.setEscHandler('n', () => {});
|
||||
parser.setEscHandler('o', () => {});
|
||||
parser.setEscHandler('|', () => {});
|
||||
parser.setEscHandler('}', () => {});
|
||||
parser.setEscHandler('~', () => {});
|
||||
parser.setEscHandler('%@', () => {});
|
||||
parser.setEscHandler('%G', () => {});
|
||||
parser.setDcsHandler('q', dcsHandler);
|
||||
});
|
||||
|
||||
perfContext('print - a', () => {
|
||||
before(() => {
|
||||
const data = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', async () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('execute - \\n', () => {
|
||||
before(() => {
|
||||
const data = '\n\n\n\n\n\n\n';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('escape - ESC E', () => {
|
||||
before(() => {
|
||||
const data = '\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE\x1bE';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('escape with collect - ESC % G', () => {
|
||||
before(() => {
|
||||
const data = '\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G\x1b%G';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('simple csi - CSI A', () => {
|
||||
before(() => {
|
||||
const data = '\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('csi with collect - CSI ? p', () => {
|
||||
before(() => {
|
||||
const data = '\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p\x1b[?p';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('csi with params - CSI 1;2 m', () => {
|
||||
before(() => {
|
||||
const data = '\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m\x1b{1;2m';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('osc (small payload) - OSC 0;hi ST', () => {
|
||||
before(() => {
|
||||
const data = '\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\\x1b]0;hi\x1b\\x1b]0;hi\x1b\\';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('osc (big payload) - OSC 0;<text> ST', () => {
|
||||
before(() => {
|
||||
const data = '\x1b]0;Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\x1b\\';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('DCS (small payload)', () => {
|
||||
before(() => {
|
||||
const data = '\x1bPq~~\x1b\\';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', async () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
|
||||
perfContext('DCS (big payload)', () => {
|
||||
before(() => {
|
||||
const data = '\x1bPq#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0#1~~@@vv@@~~@@~~$#2??}}GG}}??}}??-#1!14@\x1b\\';
|
||||
content = '';
|
||||
while (content.length < 50000000) {
|
||||
content += data;
|
||||
}
|
||||
taContent = toUtf32(content);
|
||||
});
|
||||
new ThroughputRuntimeCase('throughput', async () => {
|
||||
parser.parse(taContent, taContent.length);
|
||||
return {payloadSize: taContent.length};
|
||||
}, {fork: true}).showAverageThroughput();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user