ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

小任务只省 0.3ms、大任务命中也要 33ms:构建缓存「免费」这条共识的实测复盘

小任务只省 0.3ms、大任务命中也要 33ms:构建缓存「免费」这条共识的实测复盘 Turborepo 30K 星、Nx 29K 星、sccache 7.4K 星——2026 年内容寻址content-addressed构建缓存几乎成了 monorepo 的标配。行业文章和工具文档都在说同一件事缓存命中让重建接近零成本CI 时间砍掉 60%~80%。但翻遍这些材料你会发现一个共同的空白没有人测量过一次「命中」本身到底花了多少时间。命中不是魔法——它要走完「重新哈希全部输入 → 查找/还原产物」这条路径。如果这条路径本身不便宜那对于某些任务规模缓存可能只是「看起来快」实际净收益微乎其微。本文用一次可控的 Node 实测把冷构建和缓存命中的每一项成本拆开来看。背景为什么这件事值得写内容寻址缓存的机制很简单对任务的所有输入文件算一个哈希值作为缓存 key如果 key 命中就直接从缓存读取产物跳过整个构建步骤。Turborepo、Nx、sccache、Bazel Remote Cache 本质上都是这个模式——区别只在语言生态和分布式执行能力。2026 年的共识数据很漂亮Nx 声称大型开源项目比 Turborepo 快 7×Turborepo 文档称远程缓存可减少 70% 构建时间sccache 在 Rust 生态中能把编译时间压到三分之一。这些数字说的是有缓存 vs 无缓存的整体对比但它们隐藏了一个关键问题即使缓存 100% 命中你仍然要为每次运行付出哈希输入 还原产物的开销。当任务本身很快时这笔开销可能吃掉大部分甚至全部的加速收益。解剖一次缓存命中到底花在哪我们把一次完整的构建运行拆成四个可独立计时的阶段阶段冷构建未命中缓存命中hash 输入 → 生成 key✅ 必须✅必须重新计算无法复用上次的 keybuild / transpile / compile✅ 全量执行❌ 跳过写产物到缓存✅ 必须❌ 跳过从缓存还原产物❌ 不需要✅必须执行注意那个加粗项缓存命中仍然要重新哈希所有输入。这是因为工具不知道自上次运行以来输入是否变了——它必须重算 key 才能确认是否命中。这意味着 hash 成本是命中路径上的「固定税」随输入大小线性增长。图1100% 堆叠条形图对比。冷构建 801ms 中 build 占 94%753mswrite 占 3.6%hash 仅 2.4%缓存命中 32.8ms 中 hash 占 58.5%19.2msrestore 占 40.8%13.4ms。命中省掉了 buildwrite 这两块大头但 hash 与 restore 仍在。实证八个量级的实测方法在Node v22.22.2 (Win32 x64)上用zlib.deflateSync(input)作为 CPU 密集型构建代理真实压缩变换CPU 开销随输入大小增长用crypto.createHash(sha256)计算内容寻址 key与 Turborepo/Nx 一致用fs.readFileSync从本地磁盘还原缓存产物。对4KB ~ 48MB 共 8 个输入量级分别测量冷构建 hash(input) deflateSync(input) writeFileSync(artifact)缓存命中 re-hash(input) readFileSync(artifact)每个量级运行 5~9 轮小量级 9 轮以稳定亚毫秒计时取中位数。# 复现命令 cd 项目目录 node bench_cache.js # 输出 bench_result.json结果输入量级冷构建 (ms)缓存命中 (ms)加速倍数命中开销占冷构建比4KB0.330.065.3×19%16KB0.380.075.5×18.1%64KB1.160.0912.4×8.1%256KB4.020.2317.3×5.8%1MB16.00.6624.4×4.1%4MB63.12.5025.2×4.0%16MB252.711.322.4×4.5%48MB800.832.824.4×4.1%注数值均为各轮次中位数保留一位小数。图2加速比从 4KB 的 5.3× 逐步爬升到 ≥1MB 后的 22~25× 并趋于饱和。柱下标注了冷→热毫秒数。折线连接各量级加速比清晰展示增速放缓的趋势。三个值得关注的数字1.48MB 任务一次命中要 32.8ms。这不是零——其中 hash 花了 19.2msrestore 花了 13.4ms。在 CI 环境中32ms 单次看不大但如果你的 monorepo 有 50 个包、每次 CI 都命中 30 个包仅还原路径就消耗约 1 秒。如果是远程缓存网络往返替代本地 readFileSyncrestore 可能膨胀到 50~200ms总命中成本轻松突破 70ms/包。2.4KB 任务净省仅 0.27ms。冷构建本身就只有 0.33msbuild 0.08ms write 0.23ms命中后还要付 0.06ms 的 hashrestore。你确实快了 5 倍但绝对收益连一帧16.7ms都不到。为一个 lint 一个 10 行文件的任务引入整套缓存编排投入产出比极低。3.加速比天花板约 25×。≥1MB 后加速比稳定在 22~25× 之间不再上升因为 warm 路径的 hashrestore 自身也在随输入增大而变重。理论上如果构建是 O(n²) 而 hash 是 O(n)大任务加速比应该持续上升——但在我们的 O(n) 代理模型中hash 和 restore 都是线性的所以比值收敛。图3缓存命中耗时占冷构建的百分比。前三个量级≤64KB的开销占比高达 8%~19%橙色区域说明这些小任务的命中「税负」很重≥1MB 后稳定在 ~4%绿色净省 15ms 以上缓存才真正划算。局限哪些事没解决本次测量有几个明确的边界结论不应越界推广单任务模型我们测的是「一个构建任务」的冷/热对比没有模拟 monorepo 中多包依赖图、拓扑排序、并行执行的复杂度。真实 Turborepo/Nx 运行时还有任务调度、依赖分析等固定开销。本地磁盘缓存restore 用的是readFileSync本地 SSD 页缓存。真实场景中很多团队用远程缓存Vercel Remote Cache / Nx Cloud / S3网络延迟会把 restore 从 13ms 推到 50~200ms进一步缩小但不反转加速收益。构建代理是 O(n) 压缩真实 tsc/esbuild/swc 的构建可能是超线性或含 I/O 瓶颈加速比的绝对值会不同但「hashrestore 是命中固定税」这一结构性结论不变。没有测 correctness / 共享 ROI缓存的价值不仅是速度还包括跨机器/跨分支共享构建结果。本文只量化了单机单次的 wall-clock 收益。我们没有发现「缓存比不缓存更慢」的情况在所有 8 个量级中warm 均严格快于 cold。本文的论点不是「缓存有害」而是「缓存不是免费的——它的成本结构决定了小任务场景下收益微乎其微」。结论与下一步方法论一句话缓存那些构建本身够重的任务≥数百 KB 输入的 typecheck/bundle/transpile跳过几 KB 级别的小任务缓存——你省下的绝对时间不够抵消编排开销。同时留意命中路径的成本随着输入增大hash 和 restore 会从「可忽略」变成「不可忽略」48MB 已达 33ms远程缓存环境下更要警惕。开源地址矩阵门户GitHub - wangzifan396-wzf/WB: nano-tools: 1200 single-file, zero-dependency, local-first web utilities in one portal. Offline and private, nothing leaves your browser. Binary protocol parsers, crypto, dev, audio, visualization, productivity. · GitHub单文件工具聚合器GitHub - wangzifan396-wzf/nano-workbench: Single-file tabbed launcher for the nano-tools matrix - one tab, 382 curated tools (of 1228), instant switching. Zero-dep. Part of nano-tools. · GitHubGitHub 组织主页wangzifan396-wzf (WangZi) · GitHub
返回列表