Js使用多线程Worker和单线程异步处理数据比较
多线程worker入口文件main.js
模拟10w条数据查询或者计算时间
const { Worker } = require('worker_threads');
const os = require('os');
// 模拟100000条数据
const totalData = 100000;
const data = new Array(totalData).fill(0).map((_, i) => i + 1);
// 获取CPU核心数,确定工作线程数量
const numWorkers = os.cpus().length;
console.log(`使用 ${numWorkers} 个线程处理 ${totalData} 条数据`);
// 计算每个线程处理的数据量
const chunkSize = Math.ceil(totalData / numWorkers);
// 创建Promise数组用于等待所有线程完成
const workerPromises = [];
console.time('多线程处理时间');
// 分发任务给工作线程
for (let i = 0; i < numWorkers; i++) {
// 计算当前线程处理的数据范围
const start = i * chunkSize;
const end = Math.min(start + chunkSize, totalData);
const chunk = data.slice(start, end);
// 如果没有数据需要处理,则跳过
if (chunk.length === 0) continue;
// 创建工作线程
const workerPromise = new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', {
workerData: {
chunk,
workerId: i + 1
}
});
// 主线程监听接收子线程发回的数据
worker.on('message', ({ workerId, result }) => {
console.log(`线程 ${i + 1} 处理完成,结果: ${result}-${workerId}`);
resolve(result);
});
worker.on('error', (err) => {
console.error(`线程 ${i + 1} 发生错误:`, err);
reject(err);
});
worker.on('exit', (code) => {
if (code !== 0) {
console.error(`线程 ${i + 1} 异常退出,退出码: ${code}`);
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
});
workerPromises.push(workerPromise);
}
// 等待所有线程完成并汇总结果
Promise.all(workerPromises)
.then(results => {
console.timeEnd('多线程处理时间');
const totalResult = results.reduce((sum, result) => sum + result, 0);
console.log(`所有线程处理完成,最终结果: ${totalResult}`);
})
.catch(err => {
console.error('处理过程中发生错误:', err);
});
多线程worker.js子线程处理逻辑
const { parentPort, workerData } = require('worker_threads');
// 接收主线程传入的数据
const { chunk, workerId } = workerData;
// 模拟数据处理任务(计算平方和)
function processData(dataChunk) {
let result = 0;
for (let i = 0; i < dataChunk.length; i++) {
// 模拟复杂计算
result += dataChunk[i] * dataChunk[i];
}
return result;
}
// 执行数据处理
const result = processData(chunk);
// 将数据发送结果回主线程
parentPort.postMessage({ workerId, result });
多线程worker10w,100w, 500w,1000w,1亿条数据计算结果耗时间
多线程:使用 12 个线程处理 100000 条数据
线程 4 处理完成,结果: 7139301874851-4
线程 1 处理完成,结果: 192982263735-1
线程 7 处理完成,结果: 24504788352639-7
线程 2 处理完成,结果: 1350736926699-2
线程 6 处理完成,结果: 17558607652635-6
线程 3 处理完成,结果: 3666176797071-3
线程 5 处理完成,结果: 11770112160039-5
线程 10 处理完成,结果: 52289441697099-10
线程 11 处理完成,结果: 63866363226735-11
线程 8 处理完成,结果: 32608654260051-8
线程 9 处理完成,结果: 41870205374871-9
线程 12 处理完成,结果: 76520962763575-12
多线程处理时间: 137.53ms
所有线程处理完成,最终结果: 333338333350000
多线程:使用 12 个线程处理 1000000 条数据
线程 1 处理完成,结果: 192909336526235-1
线程 2 处理完成,结果: 1350351466489199-2
线程 5 处理完成,结果: 11767288968814268-5
线程 6 处理完成,结果: 17554471840396720-6
线程 7 处理完成,结果: 24499089897390324-7
线程 10 处理完成,结果: 52277555180801690-10
线程 12 处理完成,结果: 76575707891456480-12
线程 3 处理完成,结果: 3665228781859571-3
线程 9 处理完成,结果: 41860631567595040-9
线程 8 处理完成,结果: 32601143139793560-8
线程 4 处理完成,结果: 7137541282637351-4
线程 11 处理完成,结果: 63851913979419570-11
多线程处理时间: 157.043ms
所有线程处理完成,最终结果: 333333833333180000
多线程:使用 12 个线程处理 5000000 条数据
线程 1 处理完成,结果: 24112798997109916-1
线程 2 处理完成,结果: 168789245756800420-2
线程 3 处理完成,结果: 458141965665288260-3
线程 4 处理完成,结果: 892170958722391000-4
线程 5 处理完成,结果: 1470876224928001000-5
线程 6 处理完成,结果: 2194257764282043100-6
线程 7 处理完成,结果: 3062315576783943700-7
线程 9 处理完成,结果: 5232460021233481000-9
线程 8 处理完成,结果: 4075049662434223600-8
线程 12 处理完成,结果: 9572648736422312000-12
线程 11 处理完成,结果: 7981309558277722000-11
线程 10 处理完成,结果: 6534546653181478000-10
多线程处理时间: 187.851ms
所有线程处理完成,最终结果: 41666679166684790000
多线程:使用 12 个线程处理 10000000 条数据
线程 1 处理完成,结果: 192902044753839580-1
线程 3 处理完成,结果: 3665133989210254000-3
线程 2 处理完成,结果: 1350312924388518400-2
线程 4 处理完成,结果: 7137365239220742000-4
线程 5 处理完成,结果: 11767006674418960000-5
线程 6 处理完成,结果: 17554058294803753000-6
线程 8 处理完成,结果: 32600392091137303000-8
线程 10 处理完成,结果: 52276366628218470000-10
线程 7 处理完成,结果: 24498520100377230000-7
线程 11 处理完成,结果: 63850469174539485000-11
线程 9 处理完成,结果: 41859674267084380000-9
线程 12 处理完成,结果: 76581181905328590000-12
多线程处理时间: 282.691ms
所有线程处理完成,最终结果: 333333383333481550000
多线程:使用 12 个线程处理 100000000 条数据
线程 1 处理完成,结果: 192901315586678420000-1
线程 2 处理完成,结果: 1.3503090702170194e+21-2
线程 3 处理完成,结果: 3.6651245100325656e+21-3
线程 4 处理完成,结果: 7.137347635033739e+21-4
线程 5 处理完成,结果: 1.1766978445219803e+22-5
线程 6 处理完成,结果: 1.7554016940590916e+22-6
线程 7 处理完成,结果: 2.449846312114824e+22-7
线程 8 处理完成,结果: 3.2600316986890297e+22-8
线程 9 处理完成,结果: 4.185957853781544e+22-9
线程 10 处理完成,结果: 5.22762477739318e+22-10
线程 11 处理完成,结果: 6.385032469522634e+22-11
线程 12 处理完成,结果: 7.658172930169968e+22-12
多线程处理时间: 2.026s
所有线程处理完成,最终结果: 3.333333383333925e+23
单线程异步处理数据逻辑
main.js
// 模拟100000条数据
const totalData = 100000;
const data = new Array(totalData).fill(0).map((_, i) => i + 1);
// 异步模拟处理函数
async function processDataAsync(dataChunk, taskId) {
console.log(`任务 ${taskId} 开始处理 ${dataChunk.length} 条数据`);
let result = 0;
for (const item of dataChunk) {
// 模拟计算操作
result += item;
// 添加微小延迟模拟异步处理
if (item % 10000 === 0) {
await new Promise(resolve => setImmediate(resolve));
}
}
console.log(`任务 ${taskId} 处理完成,结果: ${result}`);
return result;
}
// 异步处理主函数
async function runAsyncProcessing() {
console.log(`使用异步方式处理 ${totalData} 条数据`);
// 获取CPU核心数,确定任务数量
const numTasks = require('os').cpus().length;
const chunkSize = Math.ceil(totalData / numTasks);
console.time('异步处理时间');
// 分割数据
const tasks = [];
for (let i = 0; i < numTasks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, totalData);
const chunk = data.slice(start, end);
if (chunk.length > 0) {
tasks.push(processDataAsync(chunk, i + 1));
}
}
// 并行执行所有任务
try {
const results = await Promise.all(tasks);
console.timeEnd('异步处理时间');
const totalResult = results.reduce((sum, result) => sum + result, 0);
console.log(`所有异步任务处理完成,最终结果: ${totalResult}`);
} catch (error) {
console.error('异步处理过程中发生错误:', error);
}
}
// 运行异步处理
runAsyncProcessing();
单线程10w,100w,1000w,1亿条数据计算结果耗时间
使用异步方式处理 100000 条数据
任务 1 开始处理 8334 条数据
任务 1 处理完成,结果: 34731945
任务 2 开始处理 8334 条数据
任务 3 开始处理 8334 条数据
任务 4 开始处理 8334 条数据
任务 5 开始处理 8334 条数据
任务 6 开始处理 8334 条数据
任务 7 开始处理 8334 条数据
任务 7 处理完成,结果: 451465281
任务 8 开始处理 8334 条数据
任务 9 开始处理 8334 条数据
任务 10 开始处理 8334 条数据
任务 11 开始处理 8334 条数据
任务 12 开始处理 8326 条数据
任务 2 处理完成,结果: 104187501
任务 3 处理完成,结果: 173643057
任务 4 处理完成,结果: 243098613
任务 5 处理完成,结果: 312554169
任务 6 处理完成,结果: 382009725
任务 8 处理完成,结果: 520920837
任务 9 处理完成,结果: 590376393
任务 10 处理完成,结果: 659831949
任务 11 处理完成,结果: 729287505
任务 12 处理完成,结果: 797943025
异步处理时间: 17.806ms
所有异步任务处理完成,最终结果: 5000050000
使用异步方式处理 1000000条数据
任务 2 开始处理 83334 条数据
任务 3 开始处理 83334 条数据
任务 4 开始处理 83334 条数据
任务 5 开始处理 83334 条数据
任务 6 开始处理 83334 条数据
任务 7 开始处理 83334 条数据
任务 8 开始处理 83334 条数据
任务 9 开始处理 83334 条数据
任务 10 开始处理 83334 条数据
任务 11 开始处理 83334 条数据
任务 12 开始处理 83326 条数据
任务 1 处理完成,结果: 3472319445
任务 2 处理完成,结果: 10416875001
任务 4 处理完成,结果: 24305986113
任务 5 处理完成,结果: 31250541669
任务 7 处理完成,结果: 45139652781
任务 8 处理完成,结果: 52084208337
任务 10 处理完成,结果: 65973319449
任务 11 处理完成,结果: 72917875005
任务 3 处理完成,结果: 17361430557
任务 6 处理完成,结果: 38195097225
任务 9 处理完成,结果: 59028763893
任务 12 处理完成,结果: 79854430525
异步处理时间: 60.151ms
所有异步任务处理完成,最终结果: 500000500000
使用异步方式处理 5000000 条数据
任务 1 开始处理 416667 条数据
任务 2 开始处理 416667 条数据
任务 3 开始处理 416667 条数据
任务 4 开始处理 416667 条数据
任务 5 开始处理 416667 条数据
任务 6 开始处理 416667 条数据
任务 7 开始处理 416667 条数据
任务 8 开始处理 416667 条数据
任务 9 开始处理 416667 条数据
任务 10 开始处理 416667 条数据
任务 11 开始处理 416667 条数据
任务 12 开始处理 416663 条数据
任务 1 处理完成,结果: 86805902778
任务 4 处理完成,结果: 607640069445
任务 7 处理完成,结果: 1128474236112
任务 10 处理完成,结果: 1649308402779
任务 2 处理完成,结果: 260417291667
任务 3 处理完成,结果: 434028680556
任务 5 处理完成,结果: 781251458334
任务 6 处理完成,结果: 954862847223
任务 8 处理完成,结果: 1302085625001
任务 9 处理完成,结果: 1475697013890
任务 11 处理完成,结果: 1822919791668
任务 12 处理完成,结果: 1996511180547
异步处理时间: 161.471ms
所有异步任务处理完成,最终结果: 12500002500000
使用异步方式处理 10000000 条数据
任务 1 开始处理 833334 条数据
任务 2 开始处理 833334 条数据
任务 3 开始处理 833334 条数据
任务 4 开始处理 833334 条数据
任务 5 开始处理 833334 条数据
任务 6 开始处理 833334 条数据
任务 7 开始处理 833334 条数据
任务 8 开始处理 833334 条数据
任务 9 开始处理 833334 条数据
任务 10 开始处理 833334 条数据
任务 11 开始处理 833334 条数据
任务 12 开始处理 833326 条数据
任务 1 处理完成,结果: 347223194445
任务 2 处理完成,结果: 1041668750001
任务 4 处理完成,结果: 2430559861113
任务 5 处理完成,结果: 3125005416669
任务 7 处理完成,结果: 4513896527781
任务 8 处理完成,结果: 5208342083337
任务 10 处理完成,结果: 6597233194449
任务 11 处理完成,结果: 7291678750005
任务 3 处理完成,结果: 1736114305557
任务 6 处理完成,结果: 3819450972225
任务 9 处理完成,结果: 5902787638893
任务 12 处理完成,结果: 7986044305525
异步处理时间: 319.762ms
所有异步任务处理完成,最终结果: 50000005000000
使用异步方式处理 100000000 条数据
任务 1 开始处理 8333334 条数据
任务 2 开始处理 8333334 条数据
任务 3 开始处理 8333334 条数据
任务 4 开始处理 8333334 条数据
任务 5 开始处理 8333334 条数据
任务 6 开始处理 8333334 条数据
任务 7 开始处理 8333334 条数据
任务 8 开始处理 8333334 条数据
任务 9 开始处理 8333334 条数据
任务 10 开始处理 8333334 条数据
任务 11 开始处理 8333334 条数据
任务 12 开始处理 8333326 条数据
任务 1 处理完成,结果: 34722231944445
任务 2 处理完成,结果: 104166687500001
任务 4 处理完成,结果: 243055598611113
任务 5 处理完成,结果: 312500054166669
任务 7 处理完成,结果: 451388965277781
任务 8 处理完成,结果: 520833420833337
任务 10 处理完成,结果: 659722331944449
任务 11 处理完成,结果: 729166787500005
任务 3 处理完成,结果: 173611143055557
任务 6 处理完成,结果: 381944509722225
任务 9 处理完成,结果: 590277876388893
任务 12 处理完成,结果: 798610443055525
异步处理时间: 2.523s
所有异步任务处理完成,最终结果: 5000000050000000
在相同计算机或者服务器下,从以上大量数据计算分析可以看出,Js多线程一般在数据量级达到千万级别处理速度优势才最明显,500w级别以下计算处理单线程速度效率优势更明显。