ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Cal.diy 性能规则解析:合并多次数组遍历,将 N 次迭代压缩为 1 次

Cal.diy 性能规则解析:合并多次数组遍历,将 N 次迭代压缩为 1 次 Cal.diy 性能规则解析合并多次数组遍历将 N 次迭代压缩为 1 次【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy本文基于 Cal.diyCal.com 开源版仓库内置的 Vercel React 最佳实践技能库深入讲解js-combine-iterations规则为什么对同一数组发起多次.filter()/.map()是应被识别和重构的性能反模式如何将其合并为单次循环以及在当前代码库中这种模式出现在哪些真实场景里。读完本文你将掌握该规则的完整判定标准、改写范式并能结合仓库源码验证其实际应用与边界。一、规则定位45 条性能规则中的 JavaScript 分类该规则定义在 js-combine-iterations.md其 YAML 元数据声明了规则的完整画像元数据字段取值含义titleCombine Multiple Array Iterations合并多次数组遍历impactLOW-MEDIUM影响等级为中低属渐进式优化非关键路径瓶颈impactDescriptionreduces iterations核心收益减少迭代次数tagsjavascript, arrays, loops, performance标签覆盖 JS、数组、循环、性能四个维度这个技能库的总览文件 SKILL.md 将 45 条规则分为 8 个按影响优先级排列的类别。js-combine-iterations位于第 7 类「JavaScript PerformanceLOW-MEDIUM」与js-index-maps为重复查找构建 Map、js-set-map-lookupsSet/Map 的 O(1) 查找、js-early-exit函数提前返回、js-min-max-loop用循环代替排序求极值等规则并列。这意味着它和消除瀑布式等待async-类CRITICAL、包体积优化bundle-类CRITICAL不在同一量级而是在热点循环内部做常数级迭代次数削减的精细优化。规则的完整展开版本见技能库的编译文档 AGENTS.md第 7.6 节内容与独立规则文件完全一致可作为 LLM/Agent 执行自动重构时的引用入口。二、规则核心反模式识别与改写范式规则原文给出的判定标准是一句话Multiple.filter()or.map()calls iterate the array multiple times. Combine into one loop. 多次.filter()或.map()调用会使数组被遍历多次。将它们合并进一个循环。2.1 反模式3 次遍历const admins users.filter(u u.isAdmin) const testers users.filter(u u.isTester) const inactive users.filter(u !u.isActive)三段代码看似各不相干但每次调用都完整扫描一遍users3 次数组遍历、3 次迭代器创建、3 个中间数组的分配。若users长度为 n总工作量是 O(3n)。2.2 正确写法1 次遍历const admins: User[] [] const testers: User[] [] const inactive: User[] [] for (const user of users) { if (user.isAdmin) admins.push(user) if (user.isTester) testers.push(user) if (!user.isActive) inactive.push(user) }改写要点有三先声明结果数组带显式类型标注User[]在循环外一次性分配单循环内并行判断每个元素只做一次属性读取和一次循环推进多个条件互不短路、互不影响因此admins、testers、inactive三个集合与多次 filter 的结果逐元素等价push摊还 O(1)总复杂度从 O(kn)k 为遍历次数降为 O(n)且只创建 1 个迭代器。这里有一个容易被忽视的等价性细节原例中isAdmin、isTester、!isActive是相互独立的谓词一个用户可能既是 admin 又是 tester所以合并为多个if是正确的如果各谓词互斥命中其一即应停止则应改用if / else if链语义与性能会不同。改写时必须先确认谓词之间是否互斥这是应用该规则时的首要检查点。三、仓库实证Cal.diy 代码库中的真实案例该规则并非纸面理论当前仓库源码中存在符合该模式的真实代码。RegularBookingService.ts 中处理团队事件的成员筛选逻辑const teamDestinationCalendars: DestinationCalendar[] []; const fixedUsers users.filter((user) user.isFixed); const nonFixedUsers users.filter((user) !user.isFixed); const filteredUsers schedulingType SchedulingType.ROUND_ROBIN ? [...fixedUsers, ...nonFixedUsers] : users;这里users被连续两次.filter()扫描且两个谓词user.isFixed/!user.isFixed互斥——这正是 2.2 节强调需要区分的场景。按该规则的范式这段代码可以改写为单循环分桶const fixedUsers: typeof users []; const nonFixedUsers: typeof users []; for (const user of users) { if (user.isFixed) { fixedUsers.push(user) } else { nonFixedUsers.push(user) } }值得注意的是此处保留双 filter 写法有一定现实合理性团队事件的用户列表规模有限一个团队成员通常几十人量级而ROUND_ROBIN模式下「固定用户排前、非固定用户排后」的拼接意图[...fixedUsers, ...nonFixedUsers]在双 filter 版本中更直白。这也体现了该规则impact: LOW-MEDIUM的定位——它是应被知晓的优化项但不是无条件强制项在数据规模小、可读性收益明显时保留原写法是合理权衡。此外data-table GUIDE.md 的示例代码中也出现了users上activeUsers与inactiveUsers两次 filter 的同类结构进一步说明「同一数组、互补谓词、双 filter 分桶」是代码库中反复出现的惯用结构值得作为该规则的标准识别模式。四、纵深关联与 O(n²) 规避规则的关系Cal.diy 的 Agent 规则库中另有一条 CRITICAL 级规则 performance-avoid-quadratic.md明确把「链式 filterChained filters和嵌套映射」列为 O(n²) 反模式的来源之一Chained filters or nested mapping over large listsArray methods like.some,.find, or.filterinside loops or callbacks两条规则构成互补关系js-combine-iterations处理的是同一数组上的横向冗余遍历k 次完整扫描 → 1 次属于常数因子优化而performance-avoid-quadratic处理的是谓词内部又对另一数组做线性扫描.filter回调里嵌套.some属于复杂度量级优化。前者将 O(kn) 压到 O(n)后者将 O(n·m) 压到 O((nm) log(nm))。在代码审查中同时应用两者时优先级应以后者为先——量级下降永远优于常数优化这与技能库把js-类规则排在 CRITICAL/HIGH 规则之后的分类逻辑一致。五、适用边界与判定清单结合规则原文与仓库实践将该规则的适用条件整理为一份可操作清单适用同一数组在相同数据状态下被 2 次及以上遍历各谓词相互独立且只做读取无副作用、无中间状态依赖数据规模足以让多次扫描产生可测量开销热路径、大数组、服务端批量处理。需谨慎谓词互斥时改用if / else if见 RegularBookingService 案例谓词之间存在依赖第二个 filter 的输入是第一个 filter 的输出时不能合并那是流水线而非冗余遍历数组规模极小且原代码意图自明时可读性可能优先于常数优化。不适用遍历次数本身很少单次 filter/map不同数组之间的多次遍历合并无从谈起异步谓词场景单循环内await会串行化应优先考虑Promise.all等并发手段对应技能库async-parallel规则。六、小结js-combine-iterations是 Vercel React 最佳实践技能库中 JavaScript 性能分类下的基础规则核心主张简单而明确对同一数组的多次.filter()/.map()应合并为单次循环用循环内分支判断替代多次完整扫描。在 Cal.diy 这样的企业级调度基础设施代码库中团队事件成员筛选等场景存在真实的多次遍历结构将其与 CRITICAL 级的 O(n²) 规避规则区分开——一个管常数、一个管量级——可以在代码审查与 AI 辅助重构中做出正确的优先级判断。规则文件、完整技能目录与上文引用的源码路径均保留在当前仓库中可供进一步查证。【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表