过早优化的实用规则

时间:2010-06-04 23:48:25

标签: iphone algorithm design-patterns

似乎短语“过早优化”是当天的热门话题。出于某种原因,特别是iphone程序员似乎认为避免过早优化是一个积极的目标,而不是简单地避免分心的自然结果。问题是,该术语开始越来越多地应用于完全不合适的案例。

例如,我看到越来越多的人说不要担心算法的复杂性,因为那是不成熟的优化(例如Help sorting an NSArray across two properties (with NSSortDescriptor?))。坦率地说,我认为这只是懒惰,并且对纪律严谨的计算机科学感到骇人听闻。

但是我想到,可能考虑到算法的复杂性和性能正在推动汇编循环展开的方式,以及其他现在认为不必要的优化技术。

你怎么看?我们现在处于决定O(n ^ n)和O(n!)复杂度算法无关的地步吗?那么O(n)vs O(n * n)呢?

您认为“过早优化”是什么?您有意或无意地避免使用哪些实用规则?

修改

我知道我的描述有点笼统,但我对具体,实用的规则或人们用来避免“预成熟优化”的最佳做法感兴趣,特别是在iphone上平台

回答这个问题需要您首先回答“什么是预成熟优化?”的问题。由于该定义明显变化很大,任何有意义的答案都要求作者定​​义该术语。这就是为什么我不认为这是一个CW问题。同样,如果人们不同意,我会改变它。

8 个答案:

答案 0 :(得分:33)

  

什么是过早优化?

过早优化是在您知道是否值得这样做之前优化代码(通常是为了提高性能)的过程。过早优化的一个示例是在对代码进行分析之前优化代码,以找出性能瓶颈所在。一个更为极端的过早优化示例是在运行程序并确定运行速度太慢之前进行优化。

  

我们现在处于决定O(n ^ n)和O(n!)复杂度算法无关的地步吗?那么O(n)vs O(n * n)呢?

这取决于n的大小以及调用代码的频率。

如果n总是小于5,则渐近性能无关紧要。在这种情况下,常量的大小将更重要。对于小n,简单的O(n * n)算法可以击败更复杂的O(n log n)算法。或者可衡量的差异可能很小,无关紧要。

我仍然认为有太多的人花时间优化90%的代码而不是10%的代码。如果某些代码几乎没有被调用,那么没有人会关心一些代码需要10ms而不是1ms。有时候做一些简单的工作和继续是一个很好的选择,即使你知道算法的复杂性不是最优的。

您花在优化很少调用的代码上的每小时花费的时间少于您添加人们实际需要的功能所花费的时间。

答案 1 :(得分:17)

我的投票支持大多数人优化他们认为的弱点,但他们没有描述。

因此,无论您对算法的了解程度如何,无论您编写 代码的程度如何,您都不知道模块外部还发生了什么。您调用的API在幕后做了什么?你能不能一直保证ops的特定顺序是最快的吗?

这就是早熟优化的含义。您认为任何未通过分析器或其他权威工具进行严格测试的优化(ops的时钟周期并不是坏事,但它只能告诉您性能特征〜实际调用比定时更重要,通常),是一个不成熟的优化。

@k_b说它远远高于我,这也是我说的。做对,简单,然后分析,然后调整。根据需要重复。

答案 2 :(得分:12)

优先顺序:1。必须工作 2.必须可维护 3.必须机器效率

那是我第一次编程课程的第一周。在 1982

“过早优化”是优先级3在优先级1或优先级2之前被考虑的任何时间。

请注意,现代编程技术(抽象和接口)旨在使此优先级更容易。

一个灰色区域:在初始设计期间,您必须检查您的解决方案本质上不是非常缓慢。否则,在至少有一些工作代码之前不要担心性能。

答案 3 :(得分:6)

对于某些人来说,优化是编写代码的乐趣的一部分,过早与否。我喜欢优化,并为了易读性而克制自己。不优化的建议是那些喜欢优化的人。

  特别是iphone程序员似乎   想到避免早产   优化作为主动目标

大多数iPhone代码都与UI相关。没有太多需要优化。不需要选择会导致性能不佳的糟糕设计,但是一旦开始编写好的设计,就不需要进行优化。因此,在这种情况下,避免优化是一个合理的目标。

答案 4 :(得分:4)

  

你认为什么是“早产儿   优化“?做什么实际规则   你有意识地使用或   无意识地避开它?

使用敏捷方法(通过与用户交互来完善需求的快速迭代)非常有用,因为当下界与用户进行下一次会话后,当前界面可能会发生巨大变化,因此更容易专注于开发必要应用程序的功能而不是性能。

如果没有,那么您花费大量时间优化在与用户进行会话后完全丢弃的功能的几次迭代应该会给您留言。

答案 5 :(得分:3)

算法复杂性,甚至选择,是一个应该隐藏在接口后面的问题。例如,List是一种抽象,可以通过各种方式实现,针对不同情况具有不同的效率。

有时避免过早优化可以帮助设计,因为如果你设计的想法是你需要稍后进行优化,那么你更倾向于在抽象层面(例如列表)而不是实现(例如数组或链接)进行开发列表)级别。

除了避免分心之外,这可以使代码更简单,更易读。如果编程到接口,则可以稍后交换不同的实现以进行优化。过早优化会导致实施细节可能过早暴露并与其他不应看到这些细节的软件组件结合使用的风险。

答案 6 :(得分:1)

  

您使用什么实用规则   有意识还是无意识地避开它?

避免不必要的优化的一种方法是考虑相对成本效益:

A)程序员优化代码+成本以测试所述优化的成本+维护由所述优化产生的更复杂代码的成本

VS

B)升级运行软件的服务器或仅购买另一台软件(如果可扩展)的成本

如果A>> B考虑这是否正确。 [暂时忽略B的环境成本,可能会或可能不会成为您组织关注的问题)

这更适用于过早优化,但它可以帮助您的开发人员注意花费时间进行优化工作是成本并且不应该除非在实际重要的事情上存在真正的可衡量的差异,否则:通过改善响应时间,需要服务器数量或客户满意度。

如果管理层无法看到减少$的好处,而客户无法在更好的响应时间内看到好处,那就问问自己为什么要这样做。

答案 7 :(得分:0)

我认为这是一个常识问题。有必要了解大局,甚至是幕后发生的事情,以便能够考虑何时所谓的“过早”行动是合理的。

我使用的解决方案是根据本地列表的内容计算新值所需的Web服务调用。实现这一点的方法是通过每个值发出一个Web请求。一次发送多个值不是过早的优化。对于多个操作使用数据库事务也是如此,即多次插入。

在算法方面,最重要的是让它尽可能简单。在这一点上担心堆栈与堆问题将是疯狂的。