代码之家  ›  专栏  ›  技术社区  ›  Alexandra Franks

在为未知设计时如何避免优化的危险?

  •  3
  • Alexandra Franks  · 技术社区  · 16 年前

    两个合伙人:

    1)假设您正在设计一种新的应用程序,并且正在开发新的算法来表达概念和内容——尝试 积极地 不要在那个阶段考虑优化技术,即使在你的头脑深处,你担心它可能会以O(N!)超过百万个元素?

    2)如果是这样的话,就说避免限制酷功能 可以 一旦运行了概念验证,就能够进行优化——如何让自己远离程序员的这种终身习惯?我一直在尝试脑力练习,纸上写道,但我在成长过程中基本上是在计算汇编程序中的时钟周期,在充分考虑功能价值之前,我不断地发现自己在否决可能的过度浪费的解决方案。

    编辑: 这是关于 设计 以前没有做过的事情(未知的),当你甚至不确定理论上是否可以做的时候,不要介意手头有无限的计算能力。因此,答案是“当然,在你有一个原型之前你必须优化 因为 这是一个既定的计算原则,“不是特别有用。

    14 回复  |  直到 13 年前
        1
  •  6
  •   Steve Jessop    16 年前

    我这么说不是因为我觉得你还不知道,而是为了在压制内心批评家的同时提供道德支持。

    关键是保持理智。

    如果你发现自己在写theta(n!)算法,这是预期的规模,然后你疯了。你必须扔掉它,所以你最好现在就开始寻找一个更好的算法,你可以实际使用。

    如果你发现自己在担心每按一次用户键就执行一次的奔腾代码是否需要10个周期或10万个周期,那你就疯了。CPU处于95%空闲状态。给它一万个简单的循环。如果必须的话,提出一个增强通知单,但是慢慢地离开组装程序。

    要决定的一件事是,这个项目是“写一个研究原型,然后把它发展成一个真正的产品”,还是“写一个研究原型”。很明显,如果研究成功,将会有另一个相关的项目。

    在后一种情况下(从评论听起来像是你的评论),你可以写一些只适用于n<=7的东西,甚至会导致从这里到辛辛那提的灯火管制。这仍然是你不确定能做的事。一旦你对这个问题有了感觉,你就会更好地了解性能问题是什么。

    你现在所做的,是在浪费时间(考虑到你的研究证明是不相关的)和浪费时间(因为你现在没有考虑一些重要的事情)之间找到平衡。你的研究风险越大,你就越应该高兴去做一些事情,担心你以后做了什么。

        2
  •  5
  •   Josh    16 年前

    我的主要答案是 Test Driven Development . 通过预先编写所有的测试,然后强制自己只编写足够的代码来实现所需的行为。如果时间和时钟周期成为一项需求,那么您可以编写测试来覆盖该场景,然后重构代码以满足这些需求。

        3
  •  2
  •   1800 INFORMATION    16 年前

    像安全性和可用性一样,性能也是从项目开始就必须考虑的问题。因此,您应该在设计时考虑到良好的性能。

        4
  •  2
  •   Captain Segfault    16 年前

    旧的Knuth路线是“我们应该忘记小效率,比如说97%的时间:过早的优化是万恶之源。”o(n!)对O(poly(n))来说不是“小效率”!

    处理类型1的最佳方法是从可能工作的最简单的事情开始(o(n!)除非不扩展超过几十个元素,否则不可能工作!)并从应用程序的其余部分封装它,以便您可以将其重写为更好的方法,前提是存在性能问题。

        5
  •  2
  •   Dark Shikari    16 年前

    优化并不完全是一种危险;它 好的 在编写代码时一定程度上考虑速度,因为当一些更简单和更快的方法可以实现时,它会阻止您实现缓慢而混乱的解决方案。它也会让你在头脑中检查一些东西是否可行。

    可能发生的最糟糕的事情是,你设计了一个大型程序,显式地忽略了优化,只是返回并发现 你的整个设计是完全无用的,因为没有完全重写它就无法优化 . 如果你在写的时候考虑到了所有的事情,这就永远不会发生——而“所有的事情”的一部分就是潜在的性能问题。

    “过早优化是万恶之源”是万恶之源。我看到过由于过度使用这个概念而使项目陷入瘫痪。在我的公司,我们有一个软件程序,可以从网络上的磁盘广播传输流。它最初是为测试目的而创建的(因此我们一次只需要几个流),但它始终符合程序的规范要求,因此它适用于更多的流,以便以后可以用于视频点播。

    因为它完全忽略了速度,所以写得一团糟;它有大量的memcpy,尽管它们不应该是必需的,但是它的ts处理代码非常慢(它实际上多次解析每个ts包),等等。它一次只处理40个流,而不是原本应该处理的数千个流,当它真正用于VOD时,我们不得不回去花大量的时间清理和重写它的大部分。

        6
  •  2
  •   Vilmantas Baranauskas    16 年前

    “首先,让它跑起来。那就快跑吧。”

    “要先完成,必须先完成。”

    慢的现有应用程序通常比超快的非现有应用程序要好。

        7
  •  2
  •   OldMan    16 年前

    首先,人们声称完成是唯一重要的事情(或几乎)。

    但如果你完成了一个有O(N!)它的主要算法很复杂,按经验法则你还没完成呢!99%的情况下,您的产品不完整且不可接受。

    合理的性能是工作产品的一部分。一个完美的表演也许不是。如果你完成一个需要6GB内存的文本编辑器来写一个简短的笔记,那么你根本就没有完成一个产品,你只是在浪费时间。您必须始终记住,不仅交付使产品完整的代码,还使其实现提供客户/用户需求的能力。如果您在这方面失败了,那么您在计划中完成代码编写就无关紧要了。

    因此,所有避免产生无用产品的优化都应该在不影响其余的设计和实现过程的情况下尽快被考虑和应用。

        8
  •  1
  •   aku    16 年前

    “积极不考虑优化”对我来说真的很奇怪。通常80/20规则工作得很好。如果您将80%的时间花在优化程序上,而不到20%的用例,那么最好不要浪费时间,除非这20%的用例真的很重要。

    至于完美主义,它没有什么问题,除非它开始放慢你的速度,使你错过时间框架。计算机编程艺术是在应用程序的美观性和功能性之间进行平衡的一种行为。帮助自己考虑学习时间管理。当您学习如何拆分和度量您的工作时,很容易决定是现在优化它,还是创建工作版本。

        9
  •  1
  •   torial    16 年前

    我认为忘记O(N!)是很合理的。算法的最坏情况。首先,你需要确定一个给定的过程是 可能的 完全。记住摩尔定律仍然有效,所以即使是坏的算法也需要更少的时间 时间 在10或20年内!

    首先对设计进行优化——例如先让它工作:—),然后对性能进行优化。这是Python程序员固有的一种权衡。通过在运行时速度较慢的语言编程,但它的级别更高(例如与C/C++相比),因此开发速度更快,Python程序员能够完成相当多的任务。然后他们专注于优化。

    一个警告是,如果完成所需的时间太长,以至于您无法确定您的算法是否正确,那么这是一个非常好的时间来担心早期的上流优化。我只遇到过几次这种情况——但很高兴知道这一点。

        10
  •  1
  •   Community Fabien Hure    7 年前

    从以下位置开始 onebyone 答案是优化代码和优化算法之间有很大的区别。

    是的,在这个阶段,优化代码会带来令人怀疑的好处。你不知道真正的瓶颈在哪里,你不知道一开始是否会有速度问题。

    但是,即使在开发算法/数据结构的这个阶段,也要注意缩放问题,这不仅是合理的,而且我怀疑这是必要的。毕竟,如果你的封底分析显示你不能在宇宙热死之前运行你闪亮的新应用程序一次就完成,那么就不会有很多问题继续下去。;-)

        11
  •  1
  •   Community Fabien Hure    7 年前

    我喜欢这个问题,所以我会给出答案,即使其他人已经回答了。

    当我在研究生院,在麻省理工学院人工智能实验室,我们一直面临这样的情况,我们试图写程序,以获得对语言、视觉、学习、推理等的理解。

    我的印象是,那些取得进展的人更喜欢写一些有意思的程序,而不是快速地做一些事情。事实上,花在担心性能上的时间基本上是从构思有趣行为上减去的。

    现在我研究的是更平淡的东西,但同样的原理也适用。如果我能得到一些有用的东西,我总能使它更快地工作。

    不过,我还是要提醒大家,软件工程现在的教学方式强烈地鼓励人们利用小毛病造山。人们被教导要创建一个类层次结构,尽可能多的抽象层,以及服务、接口规范、插件和太阳底下的一切。他们没有被教导将这些东西作为 尽可能少地 .

    其结果是软件过于复杂,难以优化,因为变更更加复杂。

    我认为避免这种情况的唯一方法是获得很多进行性能调优的经验,从而认识到导致这种过度实现的设计方法。(例如:过分强调类和数据结构。)

    Here is an example of tuning an application that has been written in the way that is generally taught.

        12
  •  0
  •   mattlant    16 年前

    我会给你讲一个小故事,讲述发生在我身上的事情,但不是真正的答案。

    我正在为一个客户端开发一个项目,其中一部分正在服务器上处理非常大的扫描(图像)。当我写代码的时候,我在寻找功能,但是我想了几种方法来优化代码,使它更快,使用更少的内存。

    现在出现了一个问题。在向潜在客户演示此软件和测试版的过程中,在演示单元(自备笔记本电脑)上,由于使用了太多内存而失败。它在带有真正大文件的dev服务器上也会失败。

    这是一个优化,还是一个已知的将来的错误。我现在是修复还是优化它?好吧,这也取决于他们的其他优先事项。

    它只是让我希望我花时间重新优化之前的代码。

        13
  •  0
  •   Tim Williscroft    16 年前

    想想操作场景。(用例)

    比如说我们正在做一个披萨店的寻宝小发明。

    用户打开机器。它必须在有意义的时间里给他看最近的比萨店。事实证明,我们的用户想快速了解:不到15秒。

    所以现在,你有任何想法,你想:这是否会永远,现实地运行在某个时间不到15秒,减少所有其他时间花在做重要的事情。

    或者你是一个交易系统:精确的金额。如果可以的话,每笔交易不到一毫秒。(他们可能会接受10毫秒),所以,阿金:你从相关场景的角度来看每个想法。

    假设它是一个电话应用程序:必须从下面开始(多少秒)

    向客户演示笔记本电脑总是一个场景。我们得把产品卖了。

    维护,其中有些人升级的东西总是一个场景。

    所以现在,作为一个例子:所有硬的,人工智能重的,Lisp定制的方法都不适合。 或者对于不同的笔画,XML服务器配置文件不够用户友好。

    看看这有什么帮助。

        14
  •  0
  •   Tim Cooper    13 年前

    如果我担心代码处理数据增长的能力,那么在我走得太远之前,我尝试以大块增量设置示例数据集,以像这样测试它:

    1000记录
    10000记录
    100000记录
    1000000记录

    看看它在哪里坏了或者变得不可用。然后,您可以根据实际数据来决定是否需要优化或重新设计核心算法。