Вот пример с рабочим потоком, который занимает ~ 600 мс на локальной машине для синхронного ввода-вывода:
const fs = require('fs');
const { isMainThread, Worker, parentPort, workerData } = require('worker_threads');
const filename = './foo.txt';
if (isMainThread) {
(async () => {
console.time('!');
await new Promise((resolve, reject) => {
const worker = new Worker(__filename, { workerData: filename });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
console.timeEnd('!');
})().catch(console.error);
} else {
for (let i = 0; i < 100; i++)
fs.readFileSync(workerData);
parentPort.postMessage('ok');
}
Тот же пример с одним потоком занимает ~ 2 с для асинхронного ввода-вывода:
const fs = require('fs');
const filename = './foo.txt';
console.time('worker');
(function read(i) {
if (i < 100) {
fs.readFile(filename, () => read(++i));
return;
}
console.timeEnd('worker');
})(0);
Очевидно, что синхронная блокировка здесь более эффективна.
Node.js ссылка на рабочий поток гласит:
Воркеры полезны для выполнения операций JavaScript, интенсивно использующих ЦП; не используйте их для ввода-вывода, так как встроенные в Node.js механизмы для асинхронного выполнения операций уже обрабатывают его более эффективно, чем рабочие потоки.
Каковы основания для этого утверждения?
В чем разница между основными и рабочими потоками в отношении ввода-вывода?
Разве цель работника не в том, чтобы не ограничиваться неблокирующими асинхронными операциями?
Каковы обстоятельства, при которых производительность ввода-вывода может быть менее эффективной в рабочих потоках?
Node.js’s built-in mechanisms for performing operations asynchronously ..(is already)... more efficient
, поэтому накладные расходы на создание потока являются пустой тратой. - person Liam   schedule 04.10.2018readFile
, вероятно, делает что-то не так или предполагает, что вы будете использовать его для файлов меньшего размера. С 40 МБ foo.txt я получаю 10 секунд дляfs.readFile
, 2,3 секунды дляfs.readFileSync
в воркере, 4,5 секунды для ручного эквивалентаfs.readFile
с использованиемfs.open
+fs.read
и 3,0 секунды при настройке размера буфера. (fs.createReadStream
сопоставимо.) - person Ry-♦   schedule 04.10.2018