克努特优化原则:过早优化是万恶之源

克努特优化原则(Knuth’s optimization principle):过早优化是万恶之源。

“过早优化是万恶之源”是软件开发届的一句名言。它来源于Donald Knuth的书《计算机编程艺术》(最早由Tony Hoare提出),以下是引用:

这句关于过早优化的原话来自于20世纪60年代出版的书。那是一个不同的时代,那时大型机和穿孔卡很常见,CPU处理周期很稀缺。所以程序优化得不好,可能会运行很长时间。

过早优化在今天该怎么理解?

今天,大多数开发团队都习惯于不断地量产代码并快速迭代,采用敏捷开发方法。如果软件中存在错误,可以很容易地将修复程序部署到Web服务器上。

现代研发过程中仍然存在过早优化的情绪。过早优化是开发人员应该一直考虑的事情,是在日常工作中应该尽量避免的事情。 防止过早优化在大型机时代适用,今天仍然适用。

一个典型的例子是一家创业公司花费大量时间试图找出如何扩展其软件以满足数百万用户。 这是一个非常值得考虑的问题,但不一定要付诸行动。 在担心处理数百万用户之前,你需要先确保100个用户喜欢并且想要使用你的产品。需要首先验证用户反馈

因此业务模式在反复试错或高速迭代阶段,过多的优化,显得很不划算。身处业务线,经常感到被需求压得喘不过气,其实是因为产品经理会更多的关注用户需求,关注业绩提升。

随着计算机系统性能从MHz,数百MHz到GHz的增加,计算机软件的性能已经不是最重要的问题(落后于其他问题)。今天,有些软件工程师将这个格言扩展到“你永远不应该优化你的代码!”,他们发现,有时候代码怎么写似乎问题都不大。

然而,在许多现代应用程序中发现的臃肿和反应迟钝的问题,迫使软件工程师重新考虑如何将Hoare的话应用于他们的项目。

查尔斯库克(http://www.cookcomputing.com/blog/archives/000084.html)的一篇简短的文章,其中一部分我在下面转载,描述了在Hoare的陈述中的问题:

我一直认为这句话经常导致软件设计师犯严重错误,因为它已经被应用到了不同的问题领域。这句话的完整版是“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.”

我同意这一点。在性能瓶颈明显之前,通常不值得花费大量时间对代码进行细枝末节的优化。但是,在设计软件时,应该从一开始就考虑性能问题。一个好的软件开发人员会自动做到这一点,他们大概知道性能问题会在哪里出现。没有经验的开发人员不会关注这个点,错误地认为在后期进行一些微调可以解决任何性能问题。

Hoare和Knuth真正说的是,软件工程师在担心微观优化(比如一个特定语句消耗多少CPU周期)之前,应该先担心其他问题(比如好的架构设计和这些架构的良好实现)。即微观优化的优先级是很低的,至少低于宏观优化(架构设计)、业务需求分析等。

过早优化的原因

1、过早优化出现在一些相对容易解决的问题上。 例如,有人对应用程序有所了解,但不确定如何开发它,那么他可能花费大量时间考虑他可以处理的不重要的事情,例如徽标设计是否会使系统看起来变得高大上。我以前在国企貌似经常发生这样的事。也许这是因为没有一个能总览全局的架构设计师,导致不太懂技术的领导或者客户钻牛角尖。

2、过早优化是一种“美好的愿景”。 例如,想要开始新的爱好的人,如打羽毛球,可能会花费数小时挑选高级装备并在他们开始训练之前规划未来的行动方案,因为这样做很有趣,而且比实际开始训练更简单!在球馆时不时就能看到,除了球技其它都很专业的“爱好者”。

3、过早优化是由于未能正确对任务进行优先级排序。 例如,正在开发软件的人可能过早地优化事情,不是因为要解决(架构、性能)问题,而是因为他们根本不知道如何制定各个研发阶段的计划,识别出各个阶段应该做的工作。这也很有可能因为团队里没有一个能总览全局的架构设计师。

该怎么做?

前几天QCon的围炉夜话,听毕玄说,“09年之前,阿里的技术团队都处于陪(业务)跑状态”。公司在不同阶段,技术团队的重心会不同。初创阶段更多重视业务,业务稳定(垄断)阶段更重视技术本身。 有经验的管理者会通过职位设置,研发力量投入比例来调节业务与“优化”之间的关系。从组织的角度,是希望大多数同学做好本职工作就能很好的平衡业务与“优化”之间的关系。例如在公司发展的某个阶段,出现了架构师这个角色。

作为研发工作的具体参与者和执行者该怎么做呢?从本质上讲,在确定是否应该优化某些内容时,应该考虑以下几个因素,应该问自己的几个重要问题:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注