首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

将 if 向上推,将 for 向下推:习语、其代数及其局限性

摘要

Push Ifs Up and Fors Down: The Idiom, Its Algebra, and Its Limits Introduction One of the recommendations from the Tiger Style document of TigerBeetle .. Centralize control flow. When splitting a larg...

the and function The caller loop control flow should ifs
2026-10-08 1 阅读 约5分钟阅读 speckx
分享:
字号:
Push Ifs Up 和 Fors Down:习语、代数及其限制 简介 TigerBeetle 的 Tiger Style 文档中的建议之一 .. 集中控制流。拆分大型函数时,尝试将所有 switch/if 语句保留在“父”函数中,并将非分支逻辑片段移至辅助函数。划分责任。所有控制流应该由一个函数处理,其余的根本不应该关心控制流。换句话说,“ifs 向上推,fors 向下推”。编程启发式 Push-ifs-up-fors-down 建议条件逻辑(if 语句)应向上移动(朝向调用者或管道中的较早位置),而迭代循环(用于操作)应向下移动(朝向批处理或稍后在紧密的无分支循环中)。这通过集中分支和利用批量操作来提高清晰度和性能。 matklad 也在博客中介绍了这一原则,并讨论了遵循这种编程习惯的许多优点。在帖子中,matklad 描述了通过以下方式优化代码: 将条件语句(“ifs”)向上推:如果函数在其输入上分支,请考虑将该分支移至调用者。考虑帖子中的示例 - 而不是 frobnicate(walrus: Option) 在内部解包选项,调用者处理 None 情况,并且函数采用普通的 Walrus 。函数的类型现在说明了它的前提条件,输入状态空间变得更窄并充当过滤的形式。但关键在于决策在哪里,而不是有多少数据流向下游。向下推循环(“fors”):将循环推迟到过滤或减少数据集之后,可以最大限度地减少不必要的计算。不要在循环中调用 frobnicate(walrus),而是提供 frobnicate_batch(walruses) 并让循环位于其中。因此,热循环在没有分支的情况下运行,并且是矢量化的候选者。两个动作组成。给定 Option 值的集合,调用者会丢弃 None 并将其余部分展开为 Vec ,然后将其交给 frobnicate_batch ,它根本不需要考虑 None 情况。让 Maybe_walruses : Vec < Option < Walrus >> = ... ;让 walruses : Vec < Walrus > = Maybe_walruses 。 into_iter() 。过滤器映射(|w|w)。收集 (); frobnicate_batch (&海象);如果您稍加思考,就会发现“上推-下推”原则有着更广泛的应用。这篇文章探讨了这一原则在关系数据库查询优化、函数式编程和范畴论方面的一些更广泛的观点。数据库查询中的类比:早期预测,晚期连接同样的原理也出现在数据库查询优化中。在 SQL 查询规划中,众所周知,应该尽早执行预测和选择,并将连接或扩展操作推迟到稍后。但词汇却颠倒了。查询计划是一棵树,其叶子是表扫描,其根生成结果。数据从叶子向上流动,因此“沿着树向下”意味着“较早执行”。当优化器谈论将谓词下推时,这意味着尽早对其进行评估,这与本文其余部分所说的“向上”或“早期”相对应。早期投影和选择(下推):用数据库术语来说,投影(例如,具有特定列的 SELECT)通过在查询执行早期仅选择必要的列来减少数据集的宽度。选择(WHERE 子句)充当过滤器。两者都作为计划树的一部分被下推,以便它们能够尽早执行并过滤掉不相关的数据,从而减少传递给后续操作的数据量。延迟连接(上推连接):连接将多个表中的数据组合在一起,计算成本很高。优化器将选择和投影移至连接下方,因此连接在较小的输入上运行。结果是昂贵的组合运算符在查询语义允许的最小输入上运行。向量化执行(“for”):下推 fors 的另一个数据库类比是执行语义的变化。火山风格的执行一次处理一行,其中每个运算符通过虚拟的 next() 对每个元组调用一次。另一种方法是矢量化或批量执行,其中每个运算符在每批大约一千个元组中调用一次,并在内部运行紧密循环。这就是 frobnicate 与 frobnicate_batch 在查询引擎级别的对比:每次调用的开销和每次调用的决策每批支付一次,并且内部循环是轻分支且缓存友好的。函数式编程和范畴论中的类比 让我们通过函数式编程和范畴论的视角来看看相同的原理。 Pushing-Ifs-Up 作为对子对象的限制 在范畴论中,当我们谈论集合的范畴(或者,宽松地,编程中的类型)时,我们可以有一个谓词 p : A -> Bool 。元素可以满足谓词,也可以不满足。现在考虑子
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱