UNPKG

5.36 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Test = void 0;
4const Fork_1 = require("./Fork");
5const Messager_1 = require("./Messager");
6const getDiff_1 = require("./getDiff");
7class ForkContext {
8 _test;
9 _processors;
10 _resolve;
11 _benchName;
12 _options;
13 _ended = false;
14 constructor(_test, _processors, _resolve, _benchName, _options) {
15 this._test = _test;
16 this._processors = _processors;
17 this._resolve = _resolve;
18 this._benchName = _benchName;
19 this._options = _options;
20 }
21 start() {
22 const setup = {
23 testIndex: this._test.index,
24 benchName: this._benchName,
25 samples: Math.min(Math.ceil(this._options.samples * 0.1), this._options.samples - this._test.samples.length),
26 time: this._options.time
27 };
28 const worker = Fork_1.Fork.fork({
29 ["ISO_BENCH_SETUP"]: JSON.stringify(setup)
30 });
31 this._listenForCompletionMessage(worker.stdio[3]);
32 this._listenForProcessExit(worker);
33 }
34 _processMessage(msg) {
35 if (!this._ended) {
36 if (msg.error != null) {
37 this._test.opMs = 0;
38 this._test.error = msg.error;
39 this._ended = true;
40 this._resolve();
41 }
42 else if (msg.done) {
43 this._ended = true;
44 if (this._test.samples.length >= this._options.samples) {
45 this._resolve();
46 }
47 else {
48 new ForkContext(this._test, this._processors, this._resolve, this._benchName, this._options).start();
49 }
50 }
51 else {
52 const sample = {
53 cycles: msg.cycles,
54 time: msg.diff,
55 ops: msg.cycles / msg.diff
56 };
57 this._test.samples.push(sample);
58 this._test.totalTime += msg.diff;
59 this._test.opMs = this._test.samples.reduce((total, sample) => total + sample.ops, 0) / this._test.samples.length;
60 for (const processor of this._processors) {
61 processor.sample && processor.sample(this._test, sample);
62 }
63 }
64 }
65 }
66 _listenForCompletionMessage(stream) {
67 let size = null;
68 stream.on("readable", () => {
69 try {
70 while (stream.readable) {
71 if (this._ended) {
72 break;
73 }
74 else if (size == null) {
75 const buffer = stream.read(2);
76 if (buffer && buffer.length === 2) {
77 size = buffer.readUint16LE();
78 }
79 else {
80 break;
81 }
82 }
83 else {
84 const buffer = stream.read(size);
85 if (buffer && buffer.length === size) {
86 size = null;
87 const message = JSON.parse(String(buffer));
88 this._processMessage(message);
89 }
90 }
91 }
92 }
93 catch (e) {
94 this._processMessage({
95 error: String(e)
96 });
97 }
98 });
99 }
100 _listenForProcessExit(worker) {
101 const errBuffer = [];
102 worker.stderr.on("data", data => errBuffer.push(data));
103 worker.on("exit", (code) => {
104 let err = `Process ended prematurely. Exit code: ${code}`;
105 if (errBuffer.length > 0) {
106 err = `${err}. Error: ${Buffer.concat(errBuffer).toString()}`;
107 }
108 this._processMessage({
109 error: err
110 });
111 });
112 }
113}
114class Test {
115 name;
116 index;
117 _callback;
118 _setup;
119 error = null;
120 opMs = 0;
121 totalTime = 0;
122 samples = [];
123 group = "";
124 constructor(name, index, _callback, _setup) {
125 this.name = name;
126 this.index = index;
127 this._callback = _callback;
128 this._setup = _setup;
129 }
130 fork(benchName, processors, options) {
131 return new Promise((resolve => {
132 const forkContext = new ForkContext(this, processors, resolve, benchName, options);
133 forkContext.start();
134 }));
135 }
136 async run(setup) {
137 (0, getDiff_1.getDiff)(1, this._callback, this._setup);
138 let cycles = 1;
139 let samples = setup.samples;
140 while (samples > 0) {
141 const diff = (0, getDiff_1.getDiff)(cycles, this._callback, this._setup);
142 if (diff >= setup.time) {
143 samples--;
144 await Messager_1.Messager.send({
145 diff: diff,
146 cycles: cycles
147 });
148 }
149 const ratio = diff > 0 ? (setup.time / diff) * 1.02 : 1.1;
150 cycles = diff >= setup.time ? Math.round(cycles * ratio) : Math.ceil(cycles * ratio);
151 }
152 }
153}
154exports.Test = Test;