Hacker News 中文摘要

RSS订阅

《“整洁”代码,糟糕性能(2023)》 -- "Clean" Code, Horrible Performance (2023)

文章摘要

文章指出,遵循“整洁代码”指南中的某些规则(如优先使用多态而非条件语句)会显著影响代码运行时性能,并可通过客观测量验证其代价。

文章总结

好的,这是根据您的要求,对原文主要内容进行的中文重述,保留了关键细节,并删减了与主题无关的内容。


文章标题: “整洁”代码,糟糕的性能

核心观点: 本文通过性能测试,论证了“整洁代码”的若干核心规则会严重损害软件性能,其代价可能高达10倍甚至20倍以上,相当于抹去了十多年的硬件发展成果。

主要内容:

文章指出,许多“整洁代码”的规则,如“优先使用多态而非if/else和switch”、“函数不应了解其操作对象的内部细节”、“函数应该短小”、“函数应只做一件事”以及“不要重复自己(DRY)”,虽然旨在提高代码的可维护性,但它们会直接影响代码的运行时结构,从而带来巨大的性能开销。

为了量化这种影响,作者使用了“整洁代码”文献中常见的形状(Shape)面积计算作为测试案例。

  1. 多态 vs. switch 语句:

    • “整洁”方式: 使用类继承和多态(虚函数)。每个形状(正方形、矩形、三角形、圆形)都是一个派生类,通过虚函数计算面积。计算总面积时,需要遍历一个指向这些形状对象的指针数组,并通过虚函数调用计算面积。
    • 测试结果: 每个形状的面积计算大约需要 35个时钟周期
    • 违反规则的方式: 使用枚举和联合体(union)将所有形状数据扁平化到一个结构体中,并使用一个 switch 语句根据类型计算面积。
    • 测试结果: 每个形状的面积计算降至约 24个时钟周期,性能提升了 1.5倍。仅此一项改变,就相当于将iPhone 14 Pro Max的性能降级到iPhone 11 Pro Max。
  2. 禁止了解内部细节 vs. 利用内部知识:

    • “整洁”方式: 每个形状类独立计算面积,代码分散,难以发现共性。
    • 违反规则的方式: 观察 switch 语句中的面积计算公式,发现它们都是“宽度 * 高度”再乘以一个系数(正方形为1,矩形为1,三角形为0.5,圆形为π)。于是,作者用一个查找表(Lookup Table)来存储这些系数,将面积计算简化为一行代码:CTable[Shape.Type] * Shape.Width * Shape.Height
    • 测试结果: 每个形状的面积计算降至约 3.0-3.5个时钟周期,性能相比“整洁”版本提升了 10倍。这相当于将2023年的CPU性能倒退至2010年的水平,抹去了12年的硬件进化。
  3. 增加复杂度后的性能差距:

    • 为了进一步测试,作者在问题中增加了“计算每个形状的角数”这一需求,并计算“角加权面积”。
    • “整洁”方式: 需要为每个形状类再添加一个虚函数来获取角数,导致代码中需要两次虚函数调用。
    • 违反规则的方式:switch 版本中增加一个 switch 语句获取角数。而在查找表版本中,只需将角数信息也预先计算并合并到查找表的系数中,代码本身几乎无需改动。
    • 测试结果: 性能差距进一步扩大。switch 版本比“整洁”版本快约 2倍,而查找表版本比“整洁”版本快近 15倍。这意味着,问题越复杂,“整洁代码”的性能惩罚就越严重。

结论:

作者认为,“整洁代码”的规则将代码架构围绕“类型”而非“操作”展开,这使得编译器难以优化,也让开发者难以进行全局性的性能改进(如使用查找表)。这种做法导致现代软件性能极其低下。

在“整洁代码”的五条核心规则中,除了“不要重复自己(DRY)”可能尚有可取之处外,其余四条(优先多态、禁止了解内部细节、函数短小、函数只做一件事)都对性能有毁灭性的影响。作者呼吁,这些规则不应再被无条件地奉为圭臬,除非同时警告开发者:“遵循这些规则,你的代码性能可能会降低15倍或更多。”

评论总结

根据评论内容,总结如下:

主要观点分歧:

  1. 支持《Clean Code》的批评者认为该书存在严重问题:

    • 教导不良实践,不值得推荐(评论2)
    • 对初级开发者有帮助,但对高级开发者有害,易导致教条主义(评论4)
    • 批评者指出,书中示例(如Shape类)是玩具问题,不反映真实场景(评论5、6)
  2. 反对批评者认为:

    • 性能问题源于开发者自身,而非原则本身(评论14)
    • 《Clean Code》旨在解决维护成本,而非性能优化(评论19)
    • 原则是低层次的,需结合架构理解使用(评论14)
  3. 平衡观点

    • 性能与可维护性存在永恒权衡,多数情况下无需极端选择(评论11)
    • 应遵循"先实现,再优化"原则(评论12)
    • OOP抽象有性能代价,但复杂代码库中值得(评论9)

关键引用: - "Clean Code is teaching many bad-practices. Too many to be recommended."(评论2) - "helpful for early developers... but harmful to late-stage developers who adopt it as dogma"(评论4) - "Performance vs. Maintainability is the infinite debate"(评论11) - "The only reason why your code is slow or bad - because you created it in such a way, not due Clean Code."(评论14)

补充信息: - 文章引发广泛讨论,相关HN帖子有739分、914条评论(评论1) - 2025年《Clean Code》第二版已修订,纠正了第一版的误解(评论17) - 批评者被指为"单人程序员"视角,不适用于团队协作(评论18)