Node.js中Memored库与RAM变量读取性能测试是否正确?
咱们一步步拆解问题,先说说为什么你的结果不对,再聊聊该怎么修正测试:
核心问题1:单次测试完全没有统计意义
你只跑了一次读取就计时,这根本反映不了真实性能。操作系统的进程调度、Node.js事件循环的其他任务、甚至终端打印的开销,都会严重干扰单次测试的结果——比如你看到RAM测试的650万纳秒,绝大部分是console.log(normalRAM)的开销(对象序列化、终端输出),而不是变量读取本身的耗时。直接读取内存里的变量,耗时应该是纳秒级甚至更低,远不到百万纳秒。
核心问题2:计时范围完全不对等
- RAM测试里,你把
console.log(normalRAM)也塞进了计时区间,但这个操作的耗时比变量读取大几个数量级。 - Memored测试的计时只覆盖了
read调用到回调执行的部分,但你忽略了:Memored的API是异步的,在单进程场景下它的回调可能被立即执行,但RAM测试的同步console.log会阻塞事件循环,反而拉长了计时。两者的计时内容完全不在一个维度上。
核心问题3:测试场景不符合Memored的设计初衷
Memored是为Node.js集群(多进程)共享内存设计的,你只fork了1个worker,相当于单进程场景——这时候Memored的内部实现和普通内存变量差异极小,甚至可能直接用普通对象存储,反而因为异步回调的调度机制,在单次测试中“看起来”更快,但这根本不是它的真实性能表现。
核心问题4:缺少预热和多次采样
Node.js的V8引擎有JIT编译器,第一次运行代码时会有编译开销。你直接跑单次测试,相当于把编译时间也算进去了。性能测试必须先预热(比如先跑几百次操作让JIT优化),然后多次运行取平均值,才能排除偶然因素。
你的初始假设其实是对的
直接访问内存变量的速度肯定比通过Memored快——哪怕是单进程场景,Memored多了一层API调用、异步回调的开销(哪怕是微任务),不可能比直接读内存更快。
修正测试的建议
1. 剥离所有无关操作
把console.log移出计时范围,只测核心的读取操作:
// RAM测试修正示例 const normalRAM = { firstname: 'qwe', lastname: 'fsa' }; let s = process.hrtime(); // 只测读取,不包含打印 const value = normalRAM; let e = process.hrtime(s); console.log("RAM读取耗时(纳秒):", e[0] * 1e9 + e[1]);
2. 多次运行取平均值
循环执行上万次读取,计算总耗时再除以次数,这样结果才可信:
// 更严谨的RAM测试 const normalRAM = { firstname: 'qwe', lastname: 'fsa' }; // 预热:让JIT完成优化 for (let i = 0; i < 1000; i++) { const v = normalRAM; } // 正式测试100万次 const testTimes = 1000000; const start = process.hrtime(); for (let i = 0; i < testTimes; i++) { const v = normalRAM; } const end = process.hrtime(start); const avgNs = (end[0] * 1e9 + end[1]) / testTimes; console.log(`RAM平均读取耗时:${avgNs.toFixed(2)}纳秒`);
3. 对齐测试场景
如果要测Memored的真实性能,就fork多个worker,在不同进程间读写;如果测单进程,也要保证两者的测试逻辑一致(比如都用异步方式执行)。这里给你一个多进程下的Memored测试示例:
import cluster from 'cluster'; import memored from 'memored'; if (cluster.isMaster) { // fork 2个worker模拟集群场景 for (let i = 0; i < 2; i++) { cluster.fork(); } } else { const testData = { firstname: 'Han', lastname: 'Solo' }; // 先在master进程存数据,worker读取 if (cluster.worker.id === 1) { memored.store('character1', testData, () => { console.log('数据已存入集群共享内存'); }); } else { // 等待数据存入后再测试 setTimeout(() => { // 预热 for (let i = 0; i < 1000; i++) { memored.read('character1', () => {}); } // 正式测试10万次 const testTimes = 100000; let count = 0; const start = process.hrtime(); function runTest() { memored.read('character1', (err, value) => { count++; if (count === testTimes) { const end = process.hrtime(start); const avgNs = (end[0] * 1e9 + end[1]) / testTimes; console.log(`Memored集群平均读取耗时:${avgNs.toFixed(2)}纳秒`); process.exit(); } else { runTest(); } }); } runTest(); }, 1000); } }
这样修正后,你应该会看到RAM变量的读取速度明显快于Memored,符合你的初始预期。
内容的提问来源于stack exchange,提问作者Houssein K

