Задать вопрос

Почему разделение на потоки работает дольше?

Пытаюсь освоить потоки в ноде, все вроде работает, но даже при разделении массива на 4 части и работе в 4 потока обычный код работает быстрее. Когда был код с факториалом все работало нормально, но когда заменил на свой то не получается обработать большой объем информации быстрее однопоточности. Что я делаю не так? (Оригинал - https://github.com/BuildingXwithJS/node-worker-fac...

const os = require('os');
const path = require('path');
const CalculateArray = require('./array.js');
const {Worker, isMainThread, parentPort, workerData} = require('worker_threads');
const inquirer = require('inquirer');
const ora = require('ora');

const userCPUCount = os.cpus().length;
const NS_PER_SEC = 1e9;
const workerPath = path.resolve('factorial-worker.js');

const calculateFactorialWithWorker = (size, max, min, number) => {
  let arr = new CalculateArray(size, max, min);
  // console.log(arr.arr)

  const segmentSize = Math.ceil(arr.arr.length / userCPUCount);
  const segments = [];

  console.log('info:', arr.arr.length, userCPUCount, segmentSize);

  for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
    const start = segmentIndex * segmentSize;
    const end = start + segmentSize;
    const segment = arr.arr.slice(start, end);
    segments.push(segment);
  }

  var promises = segments.map(
    segment =>
      new Promise((resolve, reject) => {
        const worker = new Worker(workerPath, {
          workerData: {
            numbers: segment,
            count: number
          },
        });
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', code => {
          if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`));
        });
      })
  )

  return Promise.all(promises).then(results => {
    return 100//arr.calculate(number);
  });
};

const calculatFactorial = (size, max, min, number) => {
  let arr = new CalculateArray(size, max, min);
  return arr.calculate(number);
}

const benchmarkFactorial = async (size, max, min, inputNumber, factFun, label) => {
  const spinner = ora(`Calculating with ${label}..`).start();

  const startTime = process.hrtime();
  const result = await factFun(size, max, min, inputNumber);
  const diffTime = process.hrtime(startTime);
  const time = diffTime[0] * NS_PER_SEC + diffTime[1];

  spinner.succeed(`${label} result done in: ${time}`);

  return time;
}

const run = async () => {
  const {inputNumber, inputArrSize, inputMinNumber, inputMaxNumber} = await inquirer.prompt([
    {
      type: 'input',
      name: 'inputArrSize',
      message: 'Array size:',
      default: 78060000
    },
    {
      type: 'input',
      name: 'inputMaxNumber',
      message: 'Max number:',
      default: 50800
    },
    {
      type: 'input',
      name: 'inputMinNumber',
      message: 'Min number:',
      default: 100
    },
    {
      type: 'input',
      name: 'inputNumber',
      message: 'Calculate for:',
      default: 15070
    }
  ]);

  const timeWorker = await benchmarkFactorial(inputArrSize, inputMaxNumber, inputMinNumber, inputNumber, calculateFactorialWithWorker, 'Worker');
  const timeLocal = await benchmarkFactorial(inputArrSize, inputMaxNumber, inputMinNumber, inputNumber, calculatFactorial, 'Local');
  const diff = timeLocal - timeWorker;
  console.log(`Difference between local and worker: ${Math.floor(diff / 1000000)}ms`);
};

run();

const {Worker, parentPort, workerData} = require('worker_threads');
const CalculateArray = require('./array.js');

// get the array numbers
const numbers = workerData.numbers;
const count = workerData.count;

const calculate = (arr, count) => {
  return CalculateArray.findCountedItemInArr(arr, count);
}

const result = calculate(numbers, count);

// return result
parentPort.postMessage(result);
  • Вопрос задан
  • 244 просмотра
Подписаться 3 Средний 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы