Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,68 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8');
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing', 'non-flat-existing'],
method: ['access', 'accessSync'],
n: [1e5],
});
function runBench(n, path) {
for (let i = 0; i < n; i++) {
try {
fs.accessSync(path);
} catch {
// do nothing
}
}
}
function runAsyncBench(n, path) {
(function r(cntr, path) {
if (cntr-- <= 0)
return bench.end(n);
fs.access(path, () => {
r(cntr, path);
});
})(n, path);
}
function main({ n, type, method }) {
let path;
switch (type) {
case 'existing':
path = __filename;
break;
case 'non-flat-existing':
path = tmpfile;
break;
case 'non-existing':
path = tmpdir.resolve(`.non-existing-file-${process.pid}`);
break;
default:
new Error('Invalid type');
}
if (method === 'access') {
// Warmup the filesystem - it doesn't need to use the async method
runBench(n, path);
bench.start();
runAsyncBench(n, path);
} else {
// warmup
runBench(n, path);
bench.start();
runBench(n, path);
bench.end(n);
}
}

View File

@ -0,0 +1,41 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e3],
});
function main({ n, type }) {
switch (type) {
case 'existing': {
for (let i = 0; i < n; i++) {
fs.writeFileSync(tmpdir.resolve(`chmodsync-bench-file-${i}`), 'bench');
}
bench.start();
for (let i = 0; i < n; i++) {
fs.chmodSync(tmpdir.resolve(`chmodsync-bench-file-${i}`), 0o666);
}
bench.end(n);
break;
}
case 'non-existing':
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.chmodSync(tmpdir.resolve(`chmod-non-existing-file-${i}`), 0o666);
} catch {
// do nothing
}
}
bench.end(n);
break;
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,54 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
if (process.platform === 'win32') {
console.log('Skipping: Windows does not have `getuid` or `getgid`');
process.exit(0);
}
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
method: ['chownSync', 'lchownSync'],
n: [1e4],
});
function main({ n, type, method }) {
const uid = process.getuid();
const gid = process.getgid();
const fsMethod = fs[method];
switch (type) {
case 'existing': {
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8');
bench.start();
for (let i = 0; i < n; i++) {
fsMethod(tmpfile, uid, gid);
}
bench.end(n);
break;
}
case 'non-existing': {
const path = tmpdir.resolve(`.non-existing-file-${Date.now()}`);
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
fs[method](path, uid, gid);
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,37 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['invalid', 'valid'],
n: [1e4],
});
function main({ n, type }) {
tmpdir.refresh();
const dest = tmpdir.resolve(`copy-file-bench-${process.pid}`);
let path;
switch (type) {
case 'invalid':
path = tmpdir.resolve(`.existing-file-${process.pid}`);
break;
case 'valid':
path = __filename;
break;
default:
throw new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.copyFileSync(path, dest);
} catch {
// do nothing
}
}
bench.end(n);
}

View File

@ -0,0 +1,56 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const tmpdir = require('../../test/common/tmpdir');
const bench = common.createBenchmark(main, {
n: [1, 100, 10_000],
dereference: ['true', 'false'],
force: ['true', 'false'],
});
function prepareTestDirectory() {
const testDir = tmpdir.resolve(`test-cp-${process.pid}`);
fs.mkdirSync(testDir, { recursive: true });
fs.writeFileSync(path.join(testDir, 'source.txt'), 'test content');
fs.symlinkSync(
path.join(testDir, 'source.txt'),
path.join(testDir, 'link.txt'),
);
return testDir;
}
function main({ n, dereference, force }) {
tmpdir.refresh();
const src = prepareTestDirectory();
const dest = tmpdir.resolve(`${process.pid}/subdir/cp-bench-${process.pid}`);
const options = {
recursive: true,
dereference: dereference === 'true',
force: force === 'true',
};
if (options.force) {
fs.cpSync(src, dest, { recursive: true });
}
bench.start();
for (let i = 0; i < n; i++) {
if (options.force) {
fs.cpSync(src, dest, options);
} else {
const uniqueDest = tmpdir.resolve(
`${process.pid}/subdir/cp-bench-${process.pid}-${i}`,
);
fs.cpSync(src, uniqueDest, options);
}
}
bench.end(n);
}

View File

@ -0,0 +1,38 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8');
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing', 'non-flat-existing'],
n: [1e6],
});
function main({ n, type }) {
let path;
switch (type) {
case 'existing':
path = __filename;
break;
case 'non-flat-existing':
path = tmpfile;
break;
case 'non-existing':
path = tmpdir.resolve(`.non-existing-file-${process.pid}`);
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
fs.existsSync(path);
}
bench.end(n);
}

View File

@ -0,0 +1,60 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e3],
});
function main({ n, type }) {
let files;
switch (type) {
case 'existing':
files = [];
// Populate tmpdir with mock files
for (let i = 0; i < n; i++) {
const path = tmpdir.resolve(`fchmodsync-bench-file-${i}`);
fs.writeFileSync(path, 'bench');
files.push(path);
}
break;
case 'non-existing':
files = new Array(n).fill(tmpdir.resolve(`.non-existing-file-${Date.now()}`));
break;
default:
new Error('Invalid type');
}
const fds = files.map((x) => {
// Try to open, if not return likely invalid fd (1 << 30)
try {
return fs.openSync(x, 'r');
} catch {
return 1 << 30;
}
});
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.fchmodSync(fds[i], 0o666);
} catch {
// do nothing
}
}
bench.end(n);
for (const x of fds) {
try {
fs.closeSync(x);
} catch {
// do nothing
}
}
}

View File

@ -0,0 +1,42 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8');
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e4],
});
function main({ n, type }) {
let fd;
switch (type) {
case 'existing':
fd = fs.openSync(tmpfile, 'r', 0o666);
break;
case 'non-existing':
fd = 1 << 30;
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.fsyncSync(fd);
} catch {
// do nothing
}
}
bench.end(n);
if (type === 'existing') fs.closeSync(fd);
}

View File

@ -0,0 +1,40 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const path = tmpdir.resolve(`new-file-${process.pid}`);
fs.appendFileSync(path, 'Some content.');
const bench = common.createBenchmark(main, {
type: ['invalid', 'valid'],
n: [1e4],
});
function main({ n, type }) {
let fd;
switch (type) {
case 'invalid':
fd = 1 << 30;
break;
case 'valid':
fd = fs.openSync(path, 'r+');
break;
default:
throw new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.ftruncateSync(fd, 4);
} catch {
// do nothing
}
}
bench.end(n);
if (type === 'valid') fs.closeSync(fd);
}

View File

@ -0,0 +1,59 @@
'use strict';
const common = require('../common');
const {
glob,
globSync,
promises: { glob: globAsync },
} = require('fs');
const path = require('path');
const assert = require('node:assert');
const benchmarkDirectory = path.resolve(__dirname, '..', '..');
const configs = {
n: [1e3],
dir: ['lib'],
pattern: ['**/*', '*.js', '**/**.js'],
mode: ['sync', 'promise', 'callback'],
recursive: ['true', 'false'],
};
const bench = common.createBenchmark(main, configs);
async function main(config) {
const fullPath = path.resolve(benchmarkDirectory, config.dir);
const { pattern, recursive, mode } = config;
const options = { cwd: fullPath, recursive };
const callback = (resolve, reject) => {
glob(pattern, options, (err, matches) => {
if (err) {
reject(err);
} else {
resolve(matches);
}
});
};
let noDead;
bench.start();
for (let i = 0; i < config.n; i++) {
switch (mode) {
case 'sync':
noDead = globSync(pattern, options);
break;
case 'promise':
noDead = await globAsync(pattern, options);
break;
case 'callback':
noDead = await new Promise(callback);
break;
default:
throw new Error(`Unknown mode: ${mode}`);
}
}
bench.end(config.n);
assert.ok(noDead);
}

View File

@ -0,0 +1,50 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.bench-file-data-${Date.now()}`);
fs.writeFileSync(tmpfile, 'bench-file', 'utf-8');
const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e3],
});
function main({ n, type }) {
switch (type) {
case 'valid': {
bench.start();
for (let i = 0; i < n; i++) {
fs.linkSync(tmpfile, tmpdir.resolve(`.valid-${i}`), 'file');
}
bench.end(n);
break;
}
case 'invalid': {
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.linkSync(
tmpdir.resolve(`.non-existing-file-for-linkSync-${i}`),
__filename,
'file',
);
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,44 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
recursive: ['true', 'false'],
n: [1e3],
});
function main({ n, type, recursive }) {
recursive = recursive === 'true';
let files;
switch (type) {
case 'non-existing':
files = [];
// Populate tmpdir with target dirs
for (let i = 0; i < n; i++) {
const path = tmpdir.resolve(recursive ? `rmdirsync-bench-dir-${process.pid}-${i}/a/b/c` : `rmdirsync-bench-dir-${process.pid}-${i}`);
files.push(path);
}
break;
case 'existing':
files = new Array(n).fill(__dirname);
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.mkdirSync(files[i], { recursive });
} catch {
// do nothing
}
}
bench.end(n);
}

View File

@ -0,0 +1,23 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
let dirc = 0;
const bench = common.createBenchmark(main, {
n: [1e4],
});
function main({ n }) {
bench.start();
(function r(cntr) {
if (cntr-- <= 0)
return bench.end(n);
const pathname = `${tmpdir.path}/${++dirc}/${++dirc}/${++dirc}/${++dirc}`;
fs.mkdir(pathname, { recursive: true }, (err) => {
r(cntr);
});
}(n));
}

View File

@ -0,0 +1,43 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
const bench = common.createBenchmark(main, {
type: ['valid-string', 'valid-buffer', 'invalid'],
n: [1e4],
});
function main({ n, type }) {
tmpdir.refresh();
const options = { encoding: 'utf8' };
let prefix;
let out = true;
switch (type) {
case 'valid-string':
prefix = tmpdir.resolve(`${Date.now()}`);
break;
case 'valid-buffer':
prefix = Buffer.from(tmpdir.resolve(`${Date.now()}`));
break;
case 'invalid':
prefix = tmpdir.resolve('non-existent', 'foo', 'bar');
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
out = fs.mkdtempSync(prefix, options);
} catch {
// do nothing
}
}
bench.end(n);
assert.ok(out);
}

View File

@ -0,0 +1,44 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e5],
});
function runBench({ n, path }) {
for (let i = 0; i < n; i++) {
try {
const fd = fs.openSync(path, 'r', 0o666);
fs.closeSync(fd);
} catch {
// do nothing
}
}
}
function main({ n, type }) {
let path;
switch (type) {
case 'existing':
path = __filename;
break;
case 'non-existing':
path = tmpdir.resolve(`.non-existing-file-${process.pid}`);
break;
default:
new Error('Invalid type');
}
runBench({ n, path });
bench.start();
runBench({ n, path });
bench.end(n);
}

View File

@ -0,0 +1,53 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const bench = common.createBenchmark(main, {
n: [100],
dir: [ 'lib', 'test/parallel'],
mode: [ 'async', 'sync', 'callback' ],
bufferSize: [ 4, 32, 1024 ],
});
async function main({ n, dir, mode, bufferSize }) {
const fullPath = path.resolve(__dirname, '../../', dir);
bench.start();
let counter = 0;
for (let i = 0; i < n; i++) {
if (mode === 'async') {
const dir = await fs.promises.opendir(fullPath, { bufferSize });
// eslint-disable-next-line no-unused-vars
for await (const entry of dir)
counter++;
} else if (mode === 'callback') {
const dir = await fs.promises.opendir(fullPath, { bufferSize });
await new Promise((resolve, reject) => {
function read() {
dir.read((err, entry) => {
if (err) {
reject(err);
} else if (entry === null) {
resolve(dir.close());
} else {
counter++;
read();
}
});
}
read();
});
} else {
const dir = fs.opendirSync(fullPath, { bufferSize });
while (dir.readSync() !== null)
counter++;
dir.closeSync();
}
}
bench.end(counter);
}

View File

@ -0,0 +1,43 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const testFiles = fs.readdirSync('test', { withFileTypes: true })
.filter((f) => f.isDirectory())
.map((f) => path.join(f.parentPath, f.name));
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e3],
});
function main({ n, type }) {
let files;
switch (type) {
case 'existing':
files = testFiles;
break;
case 'non-existing':
files = [tmpdir.resolve(`.non-existing-file-${Date.now()}`)];
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
for (let j = 0; j < files.length; j++) {
try {
const dir = fs.opendirSync(files[j]);
dir.closeSync();
} catch {
// do nothing
}
}
}
bench.end(n);
}

View File

@ -0,0 +1,57 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bufferSize = 1024;
const sectorSize = 512;
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e4],
});
function main({ n, type }) {
let fd;
const tmpfile = { name: tmpdir.resolve(`.existing-file-${process.pid}`),
len: bufferSize * n };
tmpfile.contents = Buffer.allocUnsafe(tmpfile.len);
for (let offset = 0; offset < tmpfile.len; offset += sectorSize) {
const fillByte = 256 * Math.random();
const nBytesToFill = Math.min(sectorSize, tmpfile.len - offset);
tmpfile.contents.fill(fillByte, offset, offset + nBytesToFill);
}
fs.writeFileSync(tmpfile.name, tmpfile.contents);
switch (type) {
case 'existing':
fd = fs.openSync(tmpfile.name, 'r', 0o666);
break;
case 'non-existing':
fd = 1 << 30;
break;
default:
new Error('Invalid type');
}
const buffer = Buffer.alloc(bufferSize);
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.readSync(fd, buffer);
} catch {
// Continue regardless of error.
}
}
bench.end(n);
if (type === 'existing') fs.closeSync(fd);
}

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const bench = common.createBenchmark(main, {
n: [10],
dir: [ 'lib', 'test/parallel'],
withFileTypes: ['true', 'false'],
});
function main({ n, dir, withFileTypes }) {
withFileTypes = withFileTypes === 'true';
const fullPath = path.resolve(__dirname, '../../', dir);
bench.start();
(function r(cntr) {
if (cntr-- <= 0)
return bench.end(n);
fs.readdir(fullPath, { withFileTypes }, () => {
r(cntr);
});
}(n));
}

View File

@ -0,0 +1,22 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const bench = common.createBenchmark(main, {
n: [10],
dir: [ 'lib', 'test/parallel'],
withFileTypes: ['true', 'false'],
});
function main({ n, dir, withFileTypes }) {
withFileTypes = withFileTypes === 'true';
const fullPath = path.resolve(__dirname, '../../', dir);
bench.start();
for (let i = 0; i < n; i++) {
fs.readdirSync(fullPath, { withFileTypes });
}
bench.end(n);
}

View File

@ -0,0 +1,54 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
if (process.platform === 'win32') {
console.log('Skipping: Windows does not play well with `symlinkSync`');
process.exit(0);
}
const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e3],
});
function main({ n, type }) {
switch (type) {
case 'valid': {
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.readlink-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'data', 'utf8');
let returnValue;
for (let i = 0; i < n; i++) {
fs.symlinkSync(tmpfile, tmpdir.resolve(`.readlink-sync-${i}`), 'file');
}
bench.start();
for (let i = 0; i < n; i++) {
returnValue = fs.readlinkSync(tmpdir.resolve(`.readlink-sync-${i}`), { encoding: 'utf8' });
}
bench.end(n);
assert.ok(returnValue);
break;
}
case 'invalid': {
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.readlinkSync(tmpdir.resolve('.non-existing-file-for-readlinkSync'));
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,58 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const exptectedBuff = Buffer.from('Benchmark Data');
const expectedLength = exptectedBuff.length;
const bufferArr = [Buffer.alloc(expectedLength)];
const filename = tmpdir.resolve('readv_sync.txt');
fs.writeFileSync(filename, exptectedBuff);
const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e5],
});
function main({ n, type }) {
let fd;
let result;
switch (type) {
case 'valid':
fd = fs.openSync(filename, 'r');
bench.start();
for (let i = 0; i < n; i++) {
result = fs.readvSync(fd, bufferArr, 0);
}
bench.end(n);
assert.strictEqual(result, expectedLength);
fs.closeSync(fd);
break;
case 'invalid': {
fd = 1 << 30;
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
result = fs.readvSync(fd, bufferArr, 0);
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
throw new Error('Invalid type');
}
}

View File

@ -0,0 +1,41 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const resolved_path = path.resolve(__dirname, '../../lib/');
const relative_path = path.relative(__dirname, '../../lib/');
const bench = common.createBenchmark(main, {
n: [1e4],
pathType: ['relative', 'resolved'],
});
function main({ n, pathType }) {
bench.start();
if (pathType === 'relative')
relativePath(n);
else
resolvedPath(n);
}
function relativePath(n) {
(function r(cntr) {
if (cntr-- <= 0)
return bench.end(n);
fs.realpath(relative_path, () => {
r(cntr);
});
}(n));
}
function resolvedPath(n) {
(function r(cntr) {
if (cntr-- <= 0)
return bench.end(n);
fs.realpath(resolved_path, () => {
r(cntr);
});
}(n));
}

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
process.chdir(__dirname);
const resolved_path = path.resolve(__dirname, '../../lib/');
const relative_path = path.relative(__dirname, '../../lib/');
const bench = common.createBenchmark(main, {
n: [1e4],
pathType: ['relative', 'resolved'],
});
function main({ n, pathType }) {
const path = pathType === 'relative' ? relative_path : resolved_path;
bench.start();
for (let i = 0; i < n; i++) {
fs.realpathSync(path);
}
bench.end(n);
}

View File

@ -0,0 +1,49 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
const bench = common.createBenchmark(main, {
type: ['invalid', 'valid'],
n: [2e3],
});
function main({ n, type }) {
switch (type) {
case 'invalid': {
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.renameSync(tmpdir.resolve(`.non-existing-file-${i}`), tmpdir.resolve(`.new-file-${i}`));
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
case 'valid': {
tmpdir.refresh();
for (let i = 0; i < n; i++) {
fs.writeFileSync(tmpdir.resolve(`.existing-file-${i}`), 'bench', 'utf8');
}
bench.start();
for (let i = 0; i < n; i++) {
fs.renameSync(
tmpdir.resolve(`.existing-file-${i}`),
tmpdir.resolve(`.new-existing-file-${i}`),
);
}
bench.end(n);
break;
}
default:
throw new Error('Invalid type');
}
}

View File

@ -0,0 +1,42 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e4],
});
function main({ n, type }) {
switch (type) {
case 'existing': {
for (let i = 0; i < n; i++) {
fs.mkdirSync(tmpdir.resolve(`rmdirsync-bench-dir-${i}`));
}
bench.start();
for (let i = 0; i < n; i++) {
fs.rmdirSync(tmpdir.resolve(`rmdirsync-bench-dir-${i}`));
}
bench.end(n);
break;
}
case 'non-existing': {
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.rmdirSync(tmpdir.resolve(`.non-existent-folder-${i}`));
} catch {
// do nothing
}
}
bench.end(n);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,28 @@
'use strict';
const common = require('../common');
const fsPromises = require('fs').promises;
const bench = common.createBenchmark(main, {
n: [20e4],
statType: ['fstat', 'lstat', 'stat'],
});
async function run(n, statType) {
const handleMode = statType === 'fstat';
const arg = handleMode ? await fsPromises.open(__filename, 'r') : __filename;
let remaining = n;
bench.start();
while (remaining-- > 0)
await (handleMode ? arg.stat() : fsPromises[statType](arg));
bench.end(n);
if (typeof arg.close === 'function')
await arg.close();
}
function main(conf) {
const n = conf.n >>> 0;
const statType = conf.statType;
run(n, statType).catch(console.log);
}

View File

@ -0,0 +1,31 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const bench = common.createBenchmark(main, {
n: [20e4],
statType: ['fstat', 'lstat', 'stat'],
});
function main({ n, statType }) {
let arg;
if (statType === 'fstat')
arg = fs.openSync(__filename, 'r');
else
arg = __filename;
bench.start();
(function r(cntr, fn) {
if (cntr-- <= 0) {
bench.end(n);
if (statType === 'fstat')
fs.closeSync(arg);
return;
}
fn(arg, () => {
r(cntr, fn);
});
}(n, fs[statType]));
}

View File

@ -0,0 +1,37 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
const bench = common.createBenchmark(main, {
n: [1e4],
statSyncType: ['fstatSync', 'lstatSync', 'statSync'],
throwType: [ 'throw', 'noThrow' ],
}, {
// fstatSync does not support throwIfNoEntry
combinationFilter: ({ statSyncType, throwType }) => !(statSyncType === 'fstatSync' && throwType === 'noThrow'),
});
function main({ n, statSyncType, throwType }) {
const arg = (statSyncType === 'fstatSync' ?
(1 << 30) :
path.join(__dirname, 'non.existent'));
const fn = fs[statSyncType];
bench.start();
for (let i = 0; i < n; i++) {
if (throwType === 'noThrow') {
fn(arg, { throwIfNoEntry: false });
} else {
try {
fn(arg);
} catch {
// Continue regardless of error.
}
}
}
bench.end(n);
}

View File

@ -0,0 +1,26 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const bench = common.createBenchmark(main, {
n: [1e4],
statSyncType: ['fstatSync', 'lstatSync', 'statSync'],
});
function main({ n, statSyncType }) {
const arg = (statSyncType === 'fstatSync' ?
fs.openSync(__filename, 'r') :
__dirname);
const fn = fs[statSyncType];
bench.start();
for (let i = 0; i < n; i++) {
fn(arg);
}
bench.end(n);
if (statSyncType === 'fstatSync')
fs.closeSync(arg);
}

View File

@ -0,0 +1,51 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
if (process.platform === 'win32') {
console.log('Skipping: Windows does not play well with `symlink`');
process.exit(0);
}
const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e3],
});
function main({ n, type }) {
switch (type) {
case 'valid': {
tmpdir.refresh();
bench.start();
for (let i = 0; i < n; i++) {
fs.symlinkSync(tmpdir.resolve('.non-existent-symlink-file'), tmpdir.resolve(`.valid-${i}`), 'file');
}
bench.end(n);
break;
}
case 'invalid': {
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.symlinkSync(
tmpdir.resolve('.non-existent-symlink-file'),
__filename,
'file',
);
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,61 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
func: [ 'utimes', 'futimes', 'lutimes' ],
n: [1e3],
});
function main({ n, type, func }) {
const useFds = func === 'futimes';
const fsFunc = fs[func + 'Sync'];
switch (type) {
case 'existing': {
const files = [];
// Populate tmpdir with mock files
for (let i = 0; i < n; i++) {
const path = tmpdir.resolve(`timessync-bench-file-${i}`);
fs.writeFileSync(path, 'bench');
files.push(useFds ? fs.openSync(path, 'r+') : path);
}
bench.start();
for (let i = 0; i < n; i++) {
fsFunc(files[i], i, i);
}
bench.end(n);
if (useFds) files.forEach((x) => {
try {
fs.closeSync(x);
} catch {
// do nothing
}
});
break;
}
case 'non-existing': {
bench.start();
for (let i = 0; i < n; i++) {
try {
fsFunc(useFds ? (1 << 30) : tmpdir.resolve(`.non-existing-file-${Date.now()}`), i, i);
} catch {
// do nothing
}
}
bench.end(n);
break;
}
default:
new Error('Invalid type');
}
}

View File

@ -0,0 +1,43 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e3],
});
function main({ n, type }) {
let files;
switch (type) {
case 'existing':
files = [];
// Populate tmpdir with mock files
for (let i = 0; i < n; i++) {
const path = tmpdir.resolve(`unlinksync-bench-file-${i}`);
fs.writeFileSync(path, 'bench');
files.push(path);
}
break;
case 'non-existing':
files = new Array(n).fill(tmpdir.resolve(`.non-existing-file-${Date.now()}`));
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.unlinkSync(files[i]);
} catch {
// do nothing
}
}
bench.end(n);
}

View File

@ -0,0 +1,43 @@
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
// Some variants are commented out as they do not show a change and just slow
const bench = common.createBenchmark(main, {
encoding: ['utf8'],
useFd: ['true', 'false'],
length: [1024, 102400, 1024 * 1024],
// useBuffer: ['true', 'false'],
useBuffer: ['false'],
// func: ['appendFile', 'writeFile'],
func: ['writeFile'],
n: [1e3],
});
function main({ n, func, encoding, length, useFd, useBuffer }) {
tmpdir.refresh();
const enc = encoding === 'undefined' ? undefined : encoding;
const path = tmpdir.resolve(`.writefilesync-file-${Date.now()}`);
useFd = useFd === 'true';
const file = useFd ? fs.openSync(path, 'w') : path;
let data = 'a'.repeat(length);
if (useBuffer === 'true') data = Buffer.from(data, encoding);
const fn = fs[func + 'Sync'];
bench.start();
for (let i = 0; i < n; ++i) {
fn(file, data, enc);
}
bench.end(n);
if (useFd) fs.closeSync(file);
}

View File

@ -0,0 +1,55 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const path = tmpdir.resolve(`new-file-${process.pid}`);
fs.writeFileSync(path, 'Some content.');
const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e5],
});
const buffer = Buffer.from('Benchmark data.');
function main({ n, type }) {
let fd;
let result;
switch (type) {
case 'valid':
fd = fs.openSync(path, 'r+');
bench.start();
for (let i = 0; i < n; i++) {
result = fs.writevSync(fd, [buffer]);
}
bench.end(n);
assert.ok(result);
fs.closeSync(fd);
break;
case 'invalid': {
fd = 1 << 30;
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
result = fs.writevSync(fd, [buffer]);
} catch {
hasError = true;
}
}
bench.end(n);
assert.ok(hasError);
break;
}
default:
throw new Error('Invalid type');
}
}

View File

@ -0,0 +1,42 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`);
fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8');
const bench = common.createBenchmark(main, {
type: ['existing', 'non-existing'],
n: [1e4],
});
function main({ n, type }) {
let fd;
switch (type) {
case 'existing':
fd = fs.openSync(tmpfile, 'r', 0o666);
break;
case 'non-existing':
fd = 1 << 30;
break;
default:
new Error('Invalid type');
}
bench.start();
for (let i = 0; i < n; i++) {
try {
fs.fdatasyncSync(fd);
} catch {
// do nothing
}
}
bench.end(n);
if (type === 'existing') fs.closeSync(fd);
}

View File

@ -0,0 +1,94 @@
// Test the throughput of the fs.WriteStream class.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
const bench = common.createBenchmark(main, {
encodingType: ['buf', 'asc', 'utf'],
filesize: [1000 * 1024],
highWaterMark: [1024, 4096, 65535, 1024 * 1024],
n: 1024,
});
function main(conf) {
const { encodingType, highWaterMark, filesize } = conf;
let { n } = conf;
let encoding = '';
switch (encodingType) {
case 'buf':
encoding = null;
break;
case 'asc':
encoding = 'ascii';
break;
case 'utf':
encoding = 'utf8';
break;
default:
throw new Error(`invalid encodingType: ${encodingType}`);
}
// Make file
const buf = Buffer.allocUnsafe(filesize);
if (encoding === 'utf8') {
// ü
for (let i = 0; i < buf.length; i++) {
buf[i] = i % 2 === 0 ? 0xC3 : 0xBC;
}
} else if (encoding === 'ascii') {
buf.fill('a');
} else {
buf.fill('x');
}
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
const ws = fs.createWriteStream(filename);
ws.on('close', runTest.bind(null, filesize, highWaterMark, encoding, n));
ws.on('drain', write);
write();
function write() {
do {
n--;
} while (false !== ws.write(buf) && n > 0);
if (n === 0)
ws.end();
}
}
function runTest(filesize, highWaterMark, encoding, n) {
assert.strictEqual(fs.statSync(filename).size, filesize * n);
const rs = fs.createReadStream(filename, {
highWaterMark,
encoding,
});
rs.on('open', () => {
bench.start();
});
let bytes = 0;
rs.on('data', (chunk) => {
bytes += chunk.length;
});
rs.on('end', () => {
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
// MB/sec
bench.end(bytes / (1024 * 1024));
});
}

View File

@ -0,0 +1,36 @@
'use strict';
const common = require('../common.js');
const fs = require('fs');
const bench = common.createBenchmark(main, {
encoding: ['undefined', 'utf8', 'ascii'],
path: ['existing', 'non-existing'],
hasFileDescriptor: ['true', 'false'],
n: [1e4],
});
function main({ n, encoding, path, hasFileDescriptor }) {
const enc = encoding === 'undefined' ? undefined : encoding;
let file;
let shouldClose = false;
if (hasFileDescriptor === 'true') {
shouldClose = path === 'existing';
file = path === 'existing' ? fs.openSync(__filename) : -1;
} else {
file = path === 'existing' ? __filename : '/tmp/not-found';
}
bench.start();
for (let i = 0; i < n; ++i) {
try {
fs.readFileSync(file, enc);
} catch {
// do nothing
}
}
bench.end(n);
if (shouldClose) {
fs.closeSync(file);
}
}

View File

@ -0,0 +1,105 @@
// Submit a mix of short and long jobs to the threadpool.
// Report total job throughput.
// If we partition the long job, overall job throughput goes up significantly.
// However, this comes at the cost of the long job throughput.
//
// Short jobs: small zip jobs.
// Long jobs: fs.readFile on a large file.
'use strict';
const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname,
`.removeme-benchmark-garbage-${process.pid}`);
const fs = require('fs');
const zlib = require('zlib');
const bench = common.createBenchmark(main, {
duration: [5],
encoding: ['', 'utf-8'],
len: [1024, 16 * 1024 * 1024],
concurrent: [1, 10],
});
function main({ len, duration, concurrent, encoding }) {
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
let data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
const zipData = Buffer.alloc(1024, 'a');
let waitConcurrent = 0;
// Plus one because of zip
const targetConcurrency = concurrent + 1;
const startedAt = Date.now();
const endAt = startedAt + (duration * 1000);
let reads = 0;
let zips = 0;
bench.start();
function stop() {
const totalOps = reads + zips;
bench.end(totalOps);
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
}
function read() {
fs.readFile(filename, encoding, afterRead);
}
function afterRead(er, data) {
if (er) {
throw er;
}
if (data.length !== len)
throw new Error('wrong number of bytes returned');
reads++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === targetConcurrency) {
stop();
} else if (!benchEnded) {
read();
}
}
function zip() {
zlib.deflate(zipData, afterZip);
}
function afterZip(er, data) {
if (er)
throw er;
zips++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === targetConcurrency) {
stop();
} else if (!benchEnded) {
zip();
}
}
// Start reads
for (let i = 0; i < concurrent; i++) read();
// Start a competing zip
zip();
}

View File

@ -0,0 +1,80 @@
// Call fs.readFile with permission system enabled
// over and over again really fast.
// Then see how many times it got called.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
const bench = common.createBenchmark(main, {
duration: [5],
encoding: ['', 'utf-8'],
len: [1024, 16 * 1024 * 1024],
concurrent: [1, 10],
}, {
flags: [
'--permission',
'--allow-fs-read=*',
'--allow-fs-write=*',
'--allow-child-process',
],
});
function main({ len, duration, concurrent, encoding }) {
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
let data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
let reads = 0;
let waitConcurrent = 0;
const startedAt = Date.now();
const endAt = startedAt + (duration * 1000);
bench.start();
function stop() {
bench.end(reads);
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
process.exit(0);
}
function read() {
fs.readFile(filename, encoding, afterRead);
}
function afterRead(er, data) {
if (er) {
throw er;
}
if (data.length !== len)
throw new Error('wrong number of bytes returned');
reads++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === concurrent) {
stop();
} else if (!benchEnded) {
read();
}
}
for (let i = 0; i < concurrent; i++) read();
}

View File

@ -0,0 +1,82 @@
// Call fs.promises.readFile over and over again really fast.
// Then see how many times it got called.
// Yes, this is a silly benchmark. Most benchmarks are silly.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
const bench = common.createBenchmark(main, {
duration: [5],
encoding: ['', 'utf-8'],
len: [
1024,
512 * 1024,
4 * 1024 ** 2,
8 * 1024 ** 2,
16 * 1024 ** 2,
32 * 1024 ** 2,
],
concurrent: [1, 10],
});
function main({ len, duration, concurrent, encoding }) {
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
let data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
let reads = 0;
let waitConcurrent = 0;
const startedAt = Date.now();
const endAt = startedAt + (duration * 1000);
bench.start();
function stop() {
bench.end(reads);
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
process.exit(0);
}
function read() {
fs.promises.readFile(filename, encoding)
.then((res) => afterRead(undefined, res))
.catch((err) => afterRead(err));
}
function afterRead(er, data) {
if (er) {
throw er;
}
if (data.length !== len)
throw new Error('wrong number of bytes returned');
reads++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === concurrent) {
stop();
} else if (!benchEnded) {
read();
}
}
for (let i = 0; i < concurrent; i++) read();
}

73
benchmark/fs/readfile.js Normal file
View File

@ -0,0 +1,73 @@
// Call fs.readFile over and over again really fast.
// Then see how many times it got called.
// Yes, this is a silly benchmark. Most benchmarks are silly.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
const bench = common.createBenchmark(main, {
duration: [5],
encoding: ['', 'utf-8', 'ascii'],
len: [1024, 16 * 1024 * 1024],
concurrent: [1, 10],
});
function main({ len, duration, concurrent, encoding }) {
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
let data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
let reads = 0;
let waitConcurrent = 0;
const startedAt = Date.now();
const endAt = startedAt + (duration * 1000);
bench.start();
function read() {
fs.readFile(filename, encoding, afterRead);
}
function stop() {
bench.end(reads);
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
process.exit(0);
}
function afterRead(er, data) {
if (er) {
throw er;
}
if (data.length !== len)
throw new Error('wrong number of bytes returned');
reads++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === concurrent) {
stop();
} else if (!benchEnded) {
read();
}
}
for (let i = 0; i < concurrent; i++) read();
}

View File

@ -0,0 +1,78 @@
// Test the throughput of the fs.WriteStream class.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
const bench = common.createBenchmark(main, {
dur: [5],
encodingType: ['buf', 'asc', 'utf'],
size: [2, 1024, 65535, 1024 * 1024],
});
function main({ dur, encodingType, size }) {
let encoding;
let chunk;
switch (encodingType) {
case 'buf':
chunk = Buffer.alloc(size, 'b');
break;
case 'asc':
chunk = 'a'.repeat(size);
encoding = 'ascii';
break;
case 'utf':
chunk = 'ü'.repeat(Math.ceil(size / 2));
encoding = 'utf8';
break;
default:
throw new Error(`invalid encodingType: ${encodingType}`);
}
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
let started = false;
let ended = false;
const f = fs.createWriteStream(filename);
f.on('drain', write);
f.on('open', write);
f.on('close', done);
f.on('finish', () => {
ended = true;
const written = fs.statSync(filename).size / 1024;
try {
fs.unlinkSync(filename);
} catch {
// Continue regardless of error.
}
bench.end(written / 1024);
});
function write() {
if (!started) {
started = true;
setTimeout(() => {
f.end();
}, dur * 1000);
bench.start();
}
while (false !== f.write(chunk, encoding));
}
function done() {
if (!ended)
f.emit('finish');
}
}

View File

@ -0,0 +1,83 @@
// Call fs.promises.writeFile over and over again really fast.
// Then see how many times it got called.
// Yes, this is a silly benchmark. Most benchmarks are silly.
'use strict';
const common = require('../common.js');
const fs = require('fs');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-benchmark-garbage-${process.pid}`);
let filesWritten = 0;
const bench = common.createBenchmark(main, {
duration: [5],
encodingType: ['buf', 'asc', 'utf'],
size: [2, 1024, 65535, 1024 * 1024],
concurrent: [1, 10],
});
function main({ encodingType, duration, concurrent, size }) {
let encoding;
let chunk;
switch (encodingType) {
case 'buf':
chunk = Buffer.alloc(size, 'b');
break;
case 'asc':
chunk = 'a'.repeat(size);
encoding = 'ascii';
break;
case 'utf':
chunk = 'ü'.repeat(Math.ceil(size / 2));
encoding = 'utf8';
break;
default:
throw new Error(`invalid encodingType: ${encodingType}`);
}
let writes = 0;
let waitConcurrent = 0;
const startedAt = Date.now();
const endAt = startedAt + (duration * 1000);
bench.start();
function stop() {
bench.end(writes);
for (let i = 0; i < filesWritten; i++) {
try {
fs.unlinkSync(`${filename}-${i}`);
} catch {
// Continue regardless of error.
}
}
process.exit(0);
}
function write() {
fs.promises.writeFile(`${filename}-${filesWritten++}`, chunk, encoding)
.then(() => afterWrite())
.catch((err) => afterWrite(err));
}
function afterWrite(er) {
if (er) {
throw er;
}
writes++;
const benchEnded = Date.now() >= endAt;
if (benchEnded && (++waitConcurrent) === concurrent) {
stop();
} else if (!benchEnded) {
write();
}
}
for (let i = 0; i < concurrent; i++) write();
}