forked from IuryPiva/Node-worker-threads-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
worker-thread-example.js
91 lines (78 loc) · 2.5 KB
/
worker-thread-example.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads')
const inquirer = require('inquirer')
const ora = require('ora')
// CALCULA QUANTAS THREADS TEM O PC DO USUÁRIO
const os = require('os')
const userCPUCount = os.cpus().length
// CALCULA O FATORIAL
const calculateFactorial = number => {
if (number === 0) {
return 1
}
return new Promise(async (resolve, reject) => {
// CRIA UM ARRAY DE 0 ATÉ O NÚMERO
const numbers = []
for (let i = 1n; i <= number; i++) {
numbers.push(i)
}
// CÁLCULA QUAL O TAMANHO DE CADA PEDAÇO QUE VAI SER EXECUTADO PARALELAMENTE
const segmentSize = Math.ceil(numbers.length / userCPUCount)
const segments = []
// ARMAZENA CADA FATIA DE SEGMENTOS EM UM ARRAY
for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
const start = segmentIndex * segmentSize
const end = start + segmentSize
const segment = numbers.slice(start, end)
segments.push(segment)
}
const results = await Promise.all(
await segments.map(
segment =>
new Promise((workerResolve, workerReject) => {
const worker = new Worker('./factorial-worker.js', {
workerData: segment
})
worker.on('message', workerResolve)
worker.on('error', workerReject)
worker.on('exit', code => {
if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`))
})
})
)
)
const finalResult = results.reduce((previousValue, currentValue) => previousValue * currentValue, 1n)
resolve(finalResult)
})
}
const calculateFactorialLocal = (number) => {
const numbers = [];
for (let i = 1n; i <= number; i++) {
numbers.push(i)
}
return numbers.reduce((previousValue, currentValue) => previousValue * currentValue, 1n)
}
const run = async () => {
while(1) {
const {number} = await inquirer.prompt([
{
type: 'input',
name: 'number',
message: 'Calculate factorial for:',
default: 10,
},
])
let label = 'multithread factorial'
let spinner = ora(`Calculating with `).start()
console.time(label)
await calculateFactorial(BigInt(number))
console.timeEnd(label)
spinner.succeed(`Done!`)
label = 'local factorial'
spinner = ora(`Calculating with `).start()
console.time(label)
calculateFactorialLocal(BigInt(number))
console.timeEnd(label)
spinner.succeed(`Done!`)
}
}
run()