我经常看到这个引号用来证明显然是错误的代码,或者那些代码(虽然其性能尚未得到衡量)可以很容易地变得更快,而又不会增加代码的大小或不影响其可读性。
总的来说,我确实认为早期的微优化可能不是一个好主意。但是,宏优化(选择O(log N)算法而不是O(N ^ 2)之类的方法)通常是值得的,应该尽早完成,因为编写O(N ^ 2)算法可能很浪费,并且然后完全抛弃它,以支持O(log N)方法。
请注意,这些单词可能是:如果O(N ^ 2)算法简单易写,那么如果结果太慢,您可以稍后将其扔掉而不会感到内。但是,如果两种算法都同样复杂,或者预期的工作量如此之大,以至于您已经知道需要使用更快的算法,那么尽早进行优化是一项明智的工程决策,从长远来看,这将减少您的总工作量。
因此,总的来说,我认为正确的方法是在开始编写代码之前找出您的选择,并有意识地为您的情况选择最佳算法。最重要的是,“过早的优化是万恶之源”这句话不是无知的借口。职业开发人员应该对一般的运营成本有一个大致的了解;他们应该知道,例如
- 弦比数字还贵
- 动态语言比静态类型的语言慢得多
- 数组/向量列表相对于链表的优势,反之亦然
- 何时使用哈希表,何时使用排序的映射以及何时使用堆
- (如果它们与移动设备一起使用),“ double”和“ int”在台式机上具有相似的性能(FP甚至可能更快),但在没有FPU的低端移动设备上,“ double”的速度可能慢一百倍;
- 在Internet上传输数据的速度比HDD访问速度慢,HDD的速度比RAM慢得多,RAM的速度比L1缓存和寄存器慢得多,并且互联网操作可能会无限期地阻塞(并且随时会失败)。
开发人员应该熟悉数据结构和算法的工具箱,以便他们可以轻松地使用正确的工具来完成工作。
拥有丰富的知识和个人工具箱,您几乎可以轻松进行优化。付出不必要的优化工作是很邪恶的(我承认不止一次陷入这种陷阱)。但是,当优化就像选择一个set / hashtable而不是一个数组一样简单,或者以double []而不是string []来存储数字列表时,为什么不这样做呢?我不确定,在这里我可能与Knuth不同,但我认为他是在谈论低级优化,而我在谈论高级优化。
请记住,该报价最初来自1974年。1974年,计算机速度缓慢,计算能力也很昂贵,这使一些开发人员倾向于逐行过度优化。我认为这就是Knuth所反对的。他并不是说“完全不用担心性能”,因为在1974年那将是一次疯狂的演讲。Knuth在解释如何优化。简而言之,应该只关注瓶颈,而在这样做之前,必须进行测量以找到瓶颈。
请注意,只有编写了要测量的程序,您才能找到瓶颈,这意味着必须先进行一些性能决策,然后再进行测量。如果您弄错了这些决定,有时很难更改。因此,最好对花费多少有一个大致的了解,以便在没有可用的硬数据时可以做出合理的决定。
优化的时间提早以及对性能的担忧程度取决于工作。在编写只运行几次的脚本时,根本不担心性能通常会完全浪费时间。但是,如果您为Microsoft或Oracle工作,并且正在使用一个库,其他成千上万的开发人员将以成千上万的不同方式使用该库,则可能需要对其进行优化,以便涵盖所有不同的库。用例有效。即便如此,对性能的需求也必须始终与对可读性,可维护性,美观性,可扩展性等的需求相平衡。