3

两方:

1)假设您正在设计一种新型应用程序,并且您正在提出新的算法来表达概念和内容 - 在那个阶段尝试主动不考虑优化技术是否有意义,甚至如果在您的脑海中,您担心它可能会以 O(N!) 超过数百万个元素而告终?

2) 如果是这样,请说避免限制在概念验证运行后您可能能够优化的酷功能——您如何阻止自己摆脱这种程序员一生的习惯?我一直在尝试心理练习,纸质笔记,但我长大后基本上是在汇编程序中计算时钟周期,并且我不断发现自己在充分考虑功能价值之前否决了过于浪费的潜在解决方案。

编辑:这是关于设计一些以前没有做过的事情(未知),当你甚至不确定它是否可以在理论上完成时,更不用说手头有无限的计算能力了。因此,“当然,您必须在拥有原型之前进行优化,因为它是一个既定的计算原则”这样的答案并不是特别有用。

4

14 回答 14

6

我说以下所有内容并不是因为我认为您还不知道,而是在您压制内心批评者的同时提供道德支持:-)

关键是保持理智。

如果你发现自己正在编写一个预期可扩展的 Theta(N!) 算法,那你就疯了。你必须把它扔掉,所以你现在最好开始寻找一个更好的算法,你可能会实际使用它。

如果您发现自己担心每次用户按键精确执行一次的 Pentium 代码是否需要 10 个周期或 10K 个周期,那您就疯了。CPU 95% 空闲。给它一万个微不足道的循环。如果必须,请提出增强票,但要慢慢地远离组装者。

一旦决定该项目是“编写研究原型,然后将其演变成真正的产品”,还是“编写研究原型”。显然期望如果研究成功,将会有另一个相关项目。

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

您正在做的事情是在现在浪费时间(考虑到您的研究证明无关紧要)与以后浪费时间(因为您现在没有考虑一些事实证明很重要的事情)之间取得平衡。你的研究风险越大,你就越应该为做某事感到高兴,并担心你以后做了什么。

于 2008-09-22T03:09:46.293 回答
5

我的主要答案是测试驱动开发。通过预先编写所有测试,你强迫自己只编写足够的代码来实现你正在寻找的行为。如果时间和时钟周期成为要求,那么您可以编写测试来覆盖该场景,然后重构您的代码以满足这些要求。

于 2008-09-22T01:05:53.203 回答
2

优化并不完全是危险。在编写代码时在某种程度上考虑速度是件好事,因为当更简单、更快的事情可以做到时,它会阻止你实施缓慢而混乱的解决方案。它还可以让您在脑海中检查某些东西是否实用。

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

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

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

于 2008-09-22T01:07:31.127 回答
2

与安全性和可用性一样,性能是从项目开始就必须考虑的事情。因此,您绝对应该在设计时考虑到良好的性能。

于 2008-09-22T01:09:53.600 回答
2

旧的 Knuth 行是“我们应该忘记小的效率,比如说大约 97% 的时间:过早的优化是万恶之源。” O(N!) 到 O(poly(N)) 不是“小效率”!

处理类型 1 的最佳方法是从可能工作的最简单的事情开始(O(N!) 不可能工作,除非你不缩放超过几十个元素!)并将它从应用程序的其余部分封装起来,所以假设会出现性能问题,您可以将其重写为更好的方法。

于 2008-09-22T01:09:55.660 回答
2

“首先,让它跑起来。然后让它跑得快。”

或者

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

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

于 2008-09-22T14:13:35.400 回答
2

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

但是,如果你完成了一个在其主要算法上具有 O(N!) 复杂度的产品,根据经验,你并没有完成它!对于 99% 的情况,您的产品不完整且不可接受。

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

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

于 2008-09-30T15:26:53.230 回答
1

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

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

于 2008-09-22T01:07:02.907 回答
1

我认为忘记算法的 O(N!) 最坏情况是很合理的。首先,您需要确定一个给定的过程是否完全可行。请记住,摩尔定律仍然有效,因此即使是糟糕的算法也将在 10 或 20 年内花费更少的时间!

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

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

于 2008-09-22T01:55:38.030 回答
1

根据onebyone的回答,优化代码和优化算法之间存在很大差异。

是的,在这个阶段优化代码的好处是值得怀疑的。你不知道真正的瓶颈在哪里,你一开始就不知道是否会出现速度问题。

但是,即使在算法/数据结构等开发的这个阶段也要注意扩展问题,这不仅是合理的,而且我怀疑是必不可少的。毕竟,如果粗略的分析表明,在宇宙的热寂发生之前,您将无法运行闪亮的新应用程序直到完成,那么继续进行下去就没有什么意义了。;-)

于 2008-09-22T04:09:30.937 回答
1

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

当我在读研究生时,在麻省理工学院人工智能实验室,我们一直面临这种情况,我们试图编写程序来理解语言、视觉、学习、推理等。

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

现在我的工作更加平淡无奇,但同样的原则也适用。如果我得到一些工作,我总是可以让它工作得更快。

然而,我要提醒的是,现在教授软件工程的方式强烈鼓励从鼹鼠丘中制造高山。人们被教导创建一个类层次结构,而不是仅仅完成它,他们可以创建尽可能多的抽象层,包括服务、接口规范、插件以及阳光下的一切。他们没有被教导尽可能少用这些东西

结果是极其复杂的软件,更难优化,因为改变起来要复杂得多。

我认为避免这种情况的唯一方法是获得大量进行性能调整的经验,并通过这种方式认识到导致这种过度复杂化的设计方法。(如:过分强调类和数据结构。)

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

于 2009-11-10T16:37:47.657 回答
0

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

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

并查看它在哪里损坏或变得无法使用。然后您可以根据实际数据决定是否需要优化或重新设计核心算法。

于 2008-09-22T01:11:29.103 回答
0

我会讲一个关于发生在我身上的小故事,但不是真正的答案。

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

现在出现了一个问题。在向潜在客户演示此软件和 beta 测试期间,在演示单元(独立笔记本电脑)上,由于使用了太多内存而失败。它在具有非常大文件的开发服务器上也会失败。

那么它是一种优化,还是一个已知的未来错误。我现在修复它还是优化它?好吧,这要确定,因为它们也是其他优先事项。

它只是让我希望我确实花时间更早地重新优化代码。

于 2008-09-22T02:00:18.753 回答
0

考虑操作场景。( 用例)

假设我们正在制作一个披萨店查找器 Gizmo。

用户打开机器。它必须在有意义的时间内向他展示最近的披萨店。事实证明,我们的用户想要快速了解:在 15 秒内。

所以现在,无论你有什么想法,你都会想:这是否会在不到 15 秒的时间内真正运行,而不是花在做重要事情上的所有其他时间......

或者你是一个交易系统:准确的总和。如果可以,请每笔交易少于一毫秒。(他们可能会接受 10 毫秒),所以,阿吉安:你从相关场景的角度看待每一个想法。

假设它是一个电话应用程序:必须在以下时间开始(多少秒)

向笔记本电脑的客户演示始终是一个场景。我们必须销售产品。

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

所以现在,作为一个例子:所有的硬、AI 重、lisp 定制的方法都不合适。或者对于不同的笔画,XML服务器配置文件不够人性化。

看看这有什么帮助。

于 2008-09-22T02:15:48.450 回答