[英]Manipulating elements of an array in parallel using node.js?
我有一个像这样的 json 对象数组 -
var resultsArr = [
{
"upvotes": "45",
"postID": "4555",
"numberOfComments": "45",
"shares":"22"
},
{
"upvotes": "21",
"postID": "4665",
"numberOfComments": "20",
"shares":"24"
},
{
"upvotes": "4",
"postID": "77366",
"numberOfComments": "0",
"shares":"4"
},
{
"upvotes": "49",
"postID": "6565",
"numberOfComments": "22",
"shares":"54",
}];
我需要计算一个数值score
基于upvotes
, numberOfComments
, shares
,然后将其推回JSON字典,使得在阵列看起来像这样的每一个对象-
var resultsArr= [{
....
},
{
"upvotes": "49",
"postID": "6565",
"numberOfComments": "22",
"shares":"54",
"score":"20"
}]
我可以使用for loop
访问此数组中的 json 对象,但根据我的理解,它按顺序访问每个元素。
鉴于数组中将有大约 100-200 个项目,如何加快分数计算过程以并行访问每个元素,从而减少计算数组中每个元素的分数所需的时间?
PS 我正在编码这个,假设数组中的元素将来可能会增长到 300-400 个元素。
下面----
下的原始答案是2015年写的,当时是真的。 从那时起,Node.js 获得了工作线程。 但是它们只能与SharedArrayBuffer
真正共享内存,并且您不能在SharedArrayBuffer
存储对象(某些序列化形式除外), SharedArrayBuffer
只能与使用数字元素的类型化数组一起使用。
您可以将数组从一个线程传输到另一个线程(发送线程无法访问它,接收线程获得访问权限),因此您可以启动 N 个线程并将数组的一部分传输到每个线程。 他们将并行处理它,并将发布结果返回到主线程。
只是一个草图:
const { Worker } = require("worker_threads"); // If still using Node.js's CJS modules
function processChunkInWorker(script, chunk) {
return new Promise((resolve, reject) => {
const w = new Worker(script, {
workerData: chunk
});
w.on("message", result => {
resolve(result);
});
});
}
async function setScores(data, workerCount = 4) {
const chunkSize = Math.round(data.length / workerCount);
await Promise.all(
Array.from({length: workerCount}, async (_, index) => {
let chunkStart = index * chunkSize;
const chunkEnd = index < workerCount - 1 ? (chunkStart + chunkSize) : data.length;
const scores = await processChunkInWorker("./calcscore.js", data.slice(chunkStart, chunkEnd));
for (const score of scores) {
data[chunkStart++].score = score;
}
})
);
}
(async () => {
try {
const data = /*...load the data...*/;
await setScores(data);
console.log(data);
} catch (e) {
console.error(e.message, e.stack);
}
})();
其中calcscore.js
类似于:
const { Worker, isMainThread, parentPort, workerData } = require("worker_threads"); // If still using Node.js's CJS modules
if (!isMainThread) {
const scores = new Float64Array(workerData.map(({upvotes, numberOfComments, shares}) => +upvotes + +numberOfComments + +shares));
parentPort.postMessage(scores, scores.buffer);
}
原答案:
如何加快分数计算过程以并行访问每个元素,从而减少计算数组中每个元素的分数所需的时间?
你不能(合理地)。 NodeJS 只运行一个线程。 为了得到执行多个线程,你必须生成一个子进程,这将是慢了很多,不仅仅是做一个线程。
300-400 个元素不算什么(即使 3-4百万也算不了什么;3M 在我的机器上大约需要 289 毫秒,4M 需要 384 毫秒)。 没有必要把事情复杂化。 只是:
resultsArr.forEach(function(entry) {
// update `entry` here
});
我通常使用这段代码
loopWithPromises = async (array, callback) => Promise.all(array.map(callback))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.