source code
/* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
contributed by Joe Farro
parts taken from solution contributed by
Jos Hirth which was modified by 10iii
modified by Roman Pletnev
multi thread by Andrey Filatkin
*/
const { Worker, isMainThread, parentPort } = require('worker_threads');
const os = require('os');
const smap = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,84,86,71,72,0,
0,67,68,0,0,77,0,75,78,0,0,0,89,83,65,65,66,87,0,82,
0,0,0,0,0,0,0,84,86,71,72,0,0,67,68,0,0,77,0,75,78,0,
0,0,89,83,65,65,66,87,0,82];
const lineLen = 60;
const fullLineLen = lineLen + 1;
const caret = '>'.charCodeAt(0);
const endLine = '\n'.charCodeAt(0);
if (isMainThread) {
mainThread();
} else {
workerThread();
}
async function mainThread() {
let worker = null;
let titleBuf = Buffer.allocUnsafe(lineLen);
let titleBufPos = 0;
let titleBufPartial = false;
let dataArray = new SharedArrayBuffer(1 << 14);
let dataBuf = Buffer.from(dataArray);
let dataBufPos = 0;
for await (let chunk of process.stdin) {
await onChunk(chunk);
}
await onSection();
await worker;
async function onChunk(chunk) {
const len = chunk.length;
let i = 0;
if (titleBufPartial) {
const endI = chunk.indexOf(endLine, i);
toTitleBuf(chunk, i, endI + 1);
titleBufPartial = false;
i += endI + 1;
}
const caretI = chunk.indexOf(caret, i);
if (caretI === -1) {
toBuf(chunk, i, len);
} else {
toBuf(chunk, i, caretI);
i = caretI;
await onSection();
const endI = chunk.indexOf(endLine, i);
if (endI !== -1) {
toTitleBuf(chunk, i, endI + 1);
return onChunk(chunk.subarray(endI + 1));
} else {
toTitleBuf(chunk, i, len);
titleBufPartial = true;
}
}
}
function toTitleBuf(buffer, from, to) {
buffer.copy(titleBuf, titleBufPos, from, to);
titleBufPos += to - from;
}
function toBuf(buffer, from, to) {
if (from === to) {
return;
}
const len = to - from;
while (dataBufPos + len > dataBuf.length) {
const newArr = new SharedArrayBuffer(dataBuf.length * 2);
const newBuf = Buffer.from(newArr);
dataBuf.copy(newBuf, 0, 0, dataBufPos);
dataArray = newArr;
dataBuf = newBuf;
}
buffer.copy(dataBuf, dataBufPos, from, to);
dataBufPos += len;
}
async function onSection() {
if (titleBufPos === 0) {
return;
}
await worker;
worker = processData(titleBuf, titleBufPos, dataBuf, dataBufPos);
titleBuf = Buffer.allocUnsafe(lineLen);
titleBufPos = 0;
titleBufPartial = false;
dataArray = new SharedArrayBuffer(dataBuf.length);
dataBuf = Buffer.from(dataArray);
dataBufPos = 0;
}
function processData(titleBuf, titleBufLen, dataBuf, dataBufLen) {
return new Promise(resolve => {
const threads = Math.max(1, os.cpus().length - 2);
const lines = Math.ceil(dataBufLen / fullLineLen);
const dataLen = dataBufLen - lines;
const chunkLen = Math.floor(dataLen / (2 * threads));
let wait = 0;
let bottomStart = 0;
let bottomRealStart = 0;
let topStart = dataLen;
let topRealStart = topStart + Math.floor(topStart / lineLen);
for (let i = 0; i < threads; i++) {
const bottomFinish = i < threads - 1 ? bottomStart + chunkLen : dataLen >> 1;
const topFinish = i < threads - 1 ? topStart - chunkLen : dataLen >> 1;
const bottomRealFinish = bottomFinish + Math.floor(bottomFinish / lineLen);
const topRealFinish = topFinish + Math.floor(topFinish / lineLen);
const worker = new Worker(__filename);
worker.postMessage({data: {
dataArray: dataBuf.buffer,
topFrom: topRealFinish,
bottomFrom: bottomRealStart,
topSize: topRealStart - topRealFinish,
bottomSize: bottomRealFinish - bottomRealStart
}});
worker.on('exit', () => {
wait--;
if (wait === 0) {
resolve();
}
});
wait++;
bottomStart = bottomFinish;
bottomRealStart = bottomRealFinish;
topStart = topFinish;
topRealStart = topRealFinish;
}
})
.then(() => {
process.stdout.write(titleBuf.subarray(0, titleBufLen));
process.stdout.write(dataBuf.subarray(0, dataBufLen));
});
}
}
function workerThread() {
parentPort.on('message', message => {
writeBuf(message.data);
process.exit();
});
function writeBuf({dataArray, topFrom, bottomFrom, topSize, bottomSize}) {
const input = new Uint8Array(dataArray, topFrom, topSize);
const output = new Uint8Array(dataArray, bottomFrom, bottomSize);
let i = topSize - 1;
let o = 0;
while (i >= 0) {
let char1 = input[i--];
if (char1 === endLine) {
char1 = input[i--];
}
let char2 = output[o++];
if (char2 === endLine) {
char2 = output[o++];
}
output[o - 1] = smap[char1];
input[i + 1] = smap[char2];
}
}
}
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
Version 4.6.2
node.js v17.8.0
Wed, 23 Mar 2022 21:29:40 GMT
MAKE:
mv revcomp.typescript-7.typescript revcomp.typescript-7.ts
/opt/src/node-v17.8.0/bin/tsc --target es2022 --strict --noEmitOnError --removeComments revcomp.typescript-7.ts
revcomp.typescript-7.ts(11,9): error TS2451: Cannot redeclare block-scoped variable 'Worker'.
revcomp.typescript-7.ts(33,9): error TS7034: Variable 'worker' implicitly has type 'any' in some locations where its type cannot be determined.
revcomp.typescript-7.ts(49,20): error TS7023: 'onChunk' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
revcomp.typescript-7.ts(49,28): error TS7006: Parameter 'chunk' implicitly has an 'any' type.
revcomp.typescript-7.ts(77,25): error TS7006: Parameter 'buffer' implicitly has an 'any' type.
revcomp.typescript-7.ts(77,33): error TS7006: Parameter 'from' implicitly has an 'any' type.
revcomp.typescript-7.ts(77,39): error TS7006: Parameter 'to' implicitly has an 'any' type.
revcomp.typescript-7.ts(82,20): error TS7006: Parameter 'buffer' implicitly has an 'any' type.
revcomp.typescript-7.ts(82,28): error TS7006: Parameter 'from' implicitly has an 'any' type.
revcomp.typescript-7.ts(82,34): error TS7006: Parameter 'to' implicitly has an 'any' type.
revcomp.typescript-7.ts(104,15): error TS7005: Variable 'worker' implicitly has an 'any' type.
revcomp.typescript-7.ts(117,26): error TS7006: Parameter 'titleBuf' implicitly has an 'any' type.
revcomp.typescript-7.ts(117,36): error TS7006: Parameter 'titleBufLen' implicitly has an 'any' type.
revcomp.typescript-7.ts(117,49): error TS7006: Parameter 'dataBuf' implicitly has an 'any' type.
revcomp.typescript-7.ts(117,58): error TS7006: Parameter 'dataBufLen' implicitly has an 'any' type.
revcomp.typescript-7.ts(143,24): error TS2339: Property 'on' does not exist on type 'Worker'.
revcomp.typescript-7.ts(146,25): error TS2794: Expected 1 arguments, but got 0. Did you forget to include 'void' in your type argument to 'Promise'?
revcomp.typescript-7.ts(165,30): error TS7006: Parameter 'message' implicitly has an 'any' type.
revcomp.typescript-7.ts(170,24): error TS7031: Binding element 'dataArray' implicitly has an 'any' type.
revcomp.typescript-7.ts(170,35): error TS7031: Binding element 'topFrom' implicitly has an 'any' type.
revcomp.typescript-7.ts(170,44): error TS7031: Binding element 'bottomFrom' implicitly has an 'any' type.
revcomp.typescript-7.ts(170,56): error TS7031: Binding element 'topSize' implicitly has an 'any' type.
revcomp.typescript-7.ts(170,65): error TS7031: Binding element 'bottomSize' implicitly has an 'any' type.
../../../../../../opt/src/node-v17.8.0/lib/node_modules/typescript/lib/lib.dom.d.ts(16467,11): error TS2451: Cannot redeclare block-scoped variable 'Worker'.
../../../../../../opt/src/node-v17.8.0/lib/node_modules/typescript/lib/lib.dom.d.ts(16481,13): error TS2451: Cannot redeclare block-scoped variable 'Worker'.
make: [/home/dunham/all-benchmarksgame/2000-benchmarksgame/nanobench/makefiles/u64q.programs.Makefile:429: revcomp.typescript-7.typescript_run] Error 1 (ignored)
4.27s to complete and log all make actions
COMMAND LINE:
/opt/src/node-v17.8.0/bin/node --use_strict revcomp.typescript-7.js 0 < revcomp-input250000.txt
PROGRAM FAILED
PROGRAM OUTPUT:
node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module '/home/dunham/all-benchmarksgame/benchmarksgame_i53330/revcomp/tmp/revcomp.typescript-7.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v17.8.0