基准测试需控制变量、多次采样取稳定值,核心是量化差异而非定性快慢;明确对比原生方法与手写柯里化实现,确保输入一致且无副作用;用performance.mark/measure多轮测量,每轮千次以上,剔除极值后取中位数或均值,并验证耗时分布收敛性。

直接用基准测试对比手写柯里化函数和原生方法的执行时间,核心在于控制变量、消除干扰、多次采样取稳定值。关键不是“谁更快”,而是“快多少”“在什么规模下开始显现差异”。
明确测试对象与控制条件
先确认你比的是哪两类实现:
- 原生方法:比如
Math.max(a, b, c)或Array.prototype.map(fn)这类引擎内置的、已高度优化的函数 - 手写柯里化:比如
const curriedMax = (a) => (b) => (c) => Math.max(a, b, c),或用通用柯里化工具(如_.curry)包装后的版本
必须确保两者输入完全一致(相同参数类型、数量、内存地址无隐式拷贝),且不包含任何副作用(如 console.log、DOM 操作、网络请求)。
使用高精度计时器与多轮采样
避免用 Date.now() 或 performance.now() 单次测量——它受事件循环、GC、CPU 调度干扰太大。推荐做法:
- 用
performance.mark()+performance.measure()配合performance.clearMarks()清理上下文 - 每组测试至少运行 1000 次,剔除首尾各 5% 的极值,取中间 90% 的中位数或平均值
- 对同一函数重复运行 5–10 轮,观察耗时分布是否收敛(标准差 / 均值
区分调用阶段:绑定开销 vs 执行开销
柯里化有两段成本:一是“生成柯里化函数”的一次性开销,二是“后续调用”的运行时开销。基准测试需分开测:
-
绑定阶段:测
curry(fn)或首次闭包构造耗时(通常可忽略,除非 fn 极复杂) -
执行阶段:测已构造好的柯里化函数连续调用(如
curriedAdd(2)(3))与等效原生调用(add(2, 3))的单次耗时差
例如,在 V8 引擎中,简单二元柯里化函数的执行开销通常比原生调用高 1.2–1.8 倍,主因是额外的函数调用栈、闭包环境查找、参数重绑定;但若柯里化后被复用数百次,绑定开销可均摊至忽略不计。
结合真实场景做压力验证
单纯微基准容易失真。建议补充一个贴近业务的复合场景:
- 构造一个含 10 万条数据的数组,分别用
arr.map(curriedTransform)和arr.map(originalTransform) - 记录总耗时、内存分配量(用 Chrome DevTools 的 Memory 面板)、是否触发 TurboFan 优化(通过
%OptimizeFunctionOnNextCall检查) - 你会发现:当柯里化函数内联失败或闭包捕获大对象时,性能差距会从 1.5× 拉大到 3× 以上
本质上,边际耗时不是固定值,它取决于 JS 引擎能否将柯里化链路识别为“可优化的静态调用路径”。现代引擎(V8、SpiderMonkey)对简单单层柯里化优化较好,但对嵌套三层以上的动态柯里化,往往放弃内联,退回到解释执行。











