编程与软件工程ubiquity.acm.org编辑精选
过早优化的谬误
The Fallacy of Premature Optimization (2009)
2017 — 2022,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这篇文章讨论“过早优化”这一说法常被误用:作者认为 Knuth 的名言并不是让人忽视性能,而是反对在尚未识别关键代码前做盲目的微观优化;架构、核心 API 和数据结构一旦定型,后期再优化代价会很高。
为什么经久不衰:它历久弥新,因为它触及性能与设计取舍的永恒争论,提醒开发者别把一句名言简化为教条。
HN 评论精选
以 bzr 败给 git 为例,说明把性能考虑全部推迟到成熟后,可能被早期架构决策锁死;应反对的是过早的微观优化。
bzr 的一位核心开发者曾分析 bzr 为何败给 git,他认为很大一部分责任在于把优化推迟到产品更成熟之后;但等到成熟时,关键架构决策已经难以更改。他说“过早优化”是个危险概念,容易暗示可以把性能考虑全部推迟,而如果 UI、核心 API 或格式很难快速实现,之后也很难推翻重来。他现在更 nuanced 的看法是:要避免的是“过早的微观优化”,关键问题是以后改成更快实现的代价有多大,以及现在写简单版本能省多少。
pmoriarty查看英文原文
There's an interesting talk by one of bzr's (formerly Bazaar's) lead developers on why bzr failed and lost to git.[1] In his view, much of the blame rested on the decision to defer optimization until the product was more mature. But by the time it was mature, key architectural decisions were made that were hard to change. Here's a salient quote: "Premature optimization" is a dangerous concept. It tends to imply you can defer all consideration of performance until you have the behaviour and UI you want. But, it turns out if the UI, core APIs or formats are hard or impossible to implement quickly, it is hard to unwind them. Now I'd have a more nuanced view of what "avoid premature optimization" means: something more like "avoid premature micro-optimization." The key question is: how expensive will it be to come back and change to a faster implementation later on, and how much does it save you to write a simple or naive one now. If there's one function or routine that is written in a straightforward way, going back to rewrite it should cost only whatever time it takes you to rewrite it, and then to test, debug and release that change. So it will often make sense to defer that work until you’re sure the requirements for the code really satisfy the user, your understanding of the problem is correct, there are no unknown bugs or edge cases, etc. However, there are some things that can make changing the code much harder and we ran into several of them... [1] - https://docs.google.com/presentation/d/1awg1CHM1w128iOBp_JOxE2DgHfywBeyjDe2bkx1vfVQ/edit
Knuth 原话上下文其实倡导识别关键 3% 后认真优化,并非为忽视性能背书。
Knuth 的原话后面还有:“但我们不应放过那关键 3% 中的机会。好的程序员不会被这种推理麻痹,他会明智地仔细审视关键代码;但只在这段代码被识别出来之后。”在这句名言之前他还说,当今许多软件工程师的常识是忽略小处的效率,但他认为这只是对某些“ penny-wise-and-pound-foolish”程序员滥用优化的过度反应;在成熟工程学科里,轻易获得的 12% 提升从不被视为微不足道。这段话出自《Structured Programming with Goto Statements》,本身就是一篇倡导优化的文章。他还指出,我们行业常常浪费许多数量级的性能:iPhone 的 CPU 远超 Cray 1,可我们居然认为程序在数据量超过一百条小记录时就出问题是正常的。
mpweiher查看英文原文
The Knuth version goes on: "Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified." Above the famous quote: "The conventional wisdom shared by many of today's software engineers calls for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being practiced by penny- wise-and-pound-foolish programmers, who can't debug or maintain their "optimized" programs. In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering. Of course I wouldn't bother making such optimizations on a one-shot job, but when it's a question of preparing quality programs, I don't want to restrict myself to tools that deny me such efficiencies." All this from "Structured Programming with Goto Statements"[1], which is an advocacy piece for optimization. And as I've written before, we as an industry typically squander many orders of magnitude of performance. An iPhone has significantly more CPU horsepower than a Cray 1 supercomputer, yet we actually think it's OK that programs have problems when their data-sets increase to over a hundred small entries (notes/tasks/etc.). Anyway, I write a lot more about this in my upcoming book: "iOS and macOS Performance Tuning: Cocoa, Cocoa Touch, Objective-C, and Swift"[2] [1] http://sbel.wisc.edu/Courses/ME964/Literature/knuthProgramming1974.pdf [2] https://www.amazon.com/iOS-macOS-Performance-Tuning-Objective-C/dp/0321842847/
局部开发环境会掩盖低效,系统级延迟和真实数据规模会让问题在生产环境集中爆发。
从我看到的情况看,低效问题最常在整个软件系统层面显现。在开发者的机器上,有本地 SSD、小数据库和很小的 working set,即使存在很大的低效也可能看不见,因为电脑就是那么快。但一旦应用和数据库之间加入网络延迟、请求时序变得不可预测,数据集又大得多,无法 100% 命中内存,原本运行正常的代码就会突然卡住,跨过某个阈值后无法以请求到达的速度处理请求。不幸的是,现代库帮助“抽象掉”数据库和网络等底层架构,很容易写出这样的代码,直到生产环境出问题才意识到。
chousuke查看英文原文
From what I've seen, the problem of inefficiency most often manifests when the entire system of software is taken as a whole. On a developer's machine with local SSD, a small database and a really small working set, even large inefficiencies can become invisible because the computer is just that fast. However, add in some network latency between the application and the database, some unpredictability about the timing of requests, and a much larger data set so that you won't hit data in memory 100% of the time, and suddenly code that was working fine grinds to a halt as it crosses a threshold where it can no longer process requests faster than they come in. Unfortunately, with modern libraries helping "abstract away" underlying architecture like databases and the network, code like this is very easy to write without even realising that there might be a problem until it hits you in production.
应讨论的是“何时算过早”,而不是把优化当成非黑即白;定义上过早优化本就是错误。
评论里还没提到一个简单观察:按定义,过早优化就是个错误——否则它只会叫“优化”。真正的问题是,什么使它“过早”?我认为 Knuth 那句名言特指编程,指在功能完成之前花时间做优化。“先做出来,再让它工作,再让它更好”这个说法站得住脚。但脱离具体情境,笼统争论什么算“过早”优化、什么算及时优化或遵循最佳实践,意义不大,因为软件开发项目的环境和上下文组合无穷无尽。
chrisweekly查看英文原文
One thing I haven't seen in the comments yet is the simple observation that premature optimization is, by definition, a mistake -- otherwise it'd merely be "optimization". The real question is, what makes it "premature"? I think Knuth (in his famous "... root of all evil" quote) was referring specifically to programming, and to spending time on optimizations prior to functional completion. The mantra, "First make it. Then make it work. Then make it better." [or similar] holds water. But it's pointless to debate in general terms what precisely constitutes a "premature" optimization, vs a merely timely one, or adherence to best practices, given the infinite combinations of circumstance and context relating to software development projects.
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选