开发人员通常会面临两种可能解决问题的方法之间的选择 - 一种是惯用的和可读的,另一种不太直观,但可能表现更好。例如,在基于C语言中,有两种方法可以将数字乘以2:
int SimpleMultiplyBy2(int x)
{
return x * 2;
}
和
int FastMultiplyBy2(int x)
{
return x << 1;
}
第一个版本更容易为技术和非技术读者选择,但第二个版本可能表现更好,因为比特移位比乘法更简单。 (现在,让我们假设编译器的优化器不会检测到并优化它,尽管这也是一个考虑因素。)
作为开发人员,最初的尝试会更好吗?
答案 0 :(得分:95)
你错过了一个。
正确性的第一个代码,然后为了清楚起见(当然,这两个经常连接!)。最后,只有你有真正需要的实证证据,你才能看到优化。过早的优化确实是邪恶的。优化几乎总是花费您的时间,清晰度和可维护性。你最好确定你买的是有价值的东西。
请注意,好的算法几乎总是胜过本地化调优。没有理由你不能拥有正确,清晰和快速的代码。你会非常幸运地开始专注于“快速”。
答案 1 :(得分:58)
首先是IMO显而易见的可读版本,直到测量到性能并且需要更快的版本。
答案 2 :(得分:46)
过早优化是编程中所有邪恶(或至少大部分)的根源。
答案 3 :(得分:19)
可读性100%
如果您的编译器无法执行“x * 2”=&gt; “x&lt;&lt; 1”优化为您 - 获得一个新的编译器!
还要记住,99.9%的程序时间用于等待用户输入,等待数据库查询并等待网络响应。除非你做了20多亿次,否则它不会引人注意。
答案 4 :(得分:8)
可读性。
性能编码有其自身的一系列挑战。 Joseph M. Newcomer说well
优化只在它发生时才有意义 事项。重要的是,重要的是 很多,但直到你知道它 重要的是,不要浪费很多时间 正在做。即使你知道这很重要, 你需要知道它的重要性。 没有性能数据,你就不会 知道要优化什么,你会 可能会优化错误的东西。
结果将是模糊的,很难 写,难以调试,很难 维护无法解决问题的代码 问题。因此它具有双重性 (a)增加的缺点 软件开发和软件 维修费用,(b)没有 性能影响。
答案 5 :(得分:8)
在您给出的示例中,99.9999%的编译器将为这两种情况生成相同的代码。这说明了我的一般规则 - 首先编写可读性和可维护性,并仅在需要时进行优化。
答案 6 :(得分:8)
可靠性可靠。除非有人抱怨,否则不要担心速度
答案 7 :(得分:5)
可读性。优化的时间是进行beta测试的时间。否则你永远不知道你需要花多少时间。
答案 8 :(得分:5)
我会首先选择可读性。考虑到这些日子我们使用的优化语言和大量加载的机器,我们以可读方式编写的大多数代码都能正常运行。
在一些非常罕见的情况下,你很确定你会有一些性能瓶颈(可能来自过去的一些糟糕体验),你设法找到一些奇怪的技巧,可以给你巨大的性能优势,你可以去那。但是你应该很好地评论该代码片段,这将有助于使其更具可读性。
答案 9 :(得分:4)
这场辩论中一个经常被忽视的因素是程序员导航,理解和修改不太可读的代码所需的额外时间。考虑到程序员每小时或更长时间花费一百美元,这是一个非常实际的成本 任何性能提升都可以通过开发中的直接额外成本来抵消。
答案 10 :(得分:4)
在那里发表评论并提供解释会使其具有可读性和快速性。
这实际上取决于项目的类型以及性能的重要性。如果你正在构建一个3D游戏,那么通常会有许多常见的优化,你可能会想要在那里投入,并且没有理由不这样做(只是不要太早带走)。但如果你做了一些棘手的事情,请对它进行评论,以便任何看着它的人知道你是如何以及为什么会变得棘手。
答案 11 :(得分:3)
答案取决于具体情况。例如,在设备驱动程序编程或游戏开发中,第二种形式是可接受的习惯用语。在商业应用中,并非如此。
您最好的选择是查看代码(或类似的成功的应用程序)以查看其他开发人员的操作方式。
答案 12 :(得分:3)
两者。你的代码应该平衡两者;可读性和性能。因为忽略任何一个都会破坏项目的投资回报率,这对于你的老板来说最重要。
可读性差导致可维护性降低,从而导致更多资源用于维护,从而降低投资回报率。
糟糕的业绩导致投资和客户群减少,导致投资回报率降低。
答案 13 :(得分:3)
使用&lt;&lt;会通过微观优化。 所以Hoare(不是Knuts)统治:
Premature optimization是万恶之源。
适用,您应该首先使用更易读的版本。
这一规则是恕我直言,经常被误用作设计无法扩展或表现良好的软件的借口。
答案 14 :(得分:2)
如果您担心代码的可读性,请不要犹豫,添加评论以提醒自己这是为什么以及为什么这样做。
答案 15 :(得分:2)
代码库越大,可读性就越重要。试图理解一些微小的功能并不是那么糟糕。 (特别是因为示例中的方法名称为您提供了线索。)对于那些刚刚退出编码的孤独天才所写的一些史诗般的超级代码来说并不是那么好,因为他终于看到了他的能力的复杂性,这就是他的意思为你写的,你永远不会理解它。
答案 16 :(得分:1)
我不在谷歌工作所以我会选择邪恶的选择。 (优化)
在Jon Bentley的“Programming Pearls”的第6章中,他描述了一个系统如何通过优化6个不同的设计级别来加速400倍。我相信,通过不关心这6个设计级别的性能,现代实现者可以轻松地在程序中实现2-3个数量级的减速。
答案 17 :(得分:1)
如果您不了解瓶颈,那么优化是没有意义的。你可能已经创造了一个令人难以置信的高效功能(通常以某种程度上的可读性为代价),却发现代码中的部分代码几乎没有运行,或者它花费的时间超过磁盘或数据库,而不是保存错误的位。 因此,在您需要测量某些东西之前,您无法进行微观优化,然后您也可以从可读性开始。 但是,在设计整体架构时,您应该注意速度和可理解性,因为两者都会产生巨大影响并且难以改变(取决于编码风格和方法)。
答案 18 :(得分:1)
正如几乎每个人在答案中所说,我赞成可读性。我运行的100个项目中有99个没有硬响应时间要求,所以这是一个简单的选择。
在开始编码之前,您应该已经知道了答案。有些项目有一定的性能要求,比如“需要能够以Y(毫秒)秒运行任务X”。如果是这种情况,那么您就有了努力的目标,并且您知道何时需要进行优化。 (希望如此)这是在项目的需求阶段确定的,而不是在编写代码时确定的。
良好的可读性和以后优化的能力是正确的软件设计的结果。如果您的软件设计合理,您应该能够隔离软件的一部分并在需要时重写它们,而不会破坏系统的其他部分。此外,我遇到的大多数真正的优化案例(忽略了一些真正的低级技巧,这些都是偶然的)已经从一种算法转换到另一种算法,或者将数据缓存到内存而不是磁盘/网络。
答案 19 :(得分:1)
据估计,大约70%的软件成本在维护中。可读性使系统更易于维护,因此降低了软件的使用寿命。
有些情况下,性能对可读性更为重要,即表示它们很少且很远。
在牺牲可读性之前,请考虑“我(或您的公司)是否准备好通过这样做来处理我添加到系统中的额外成本?”
答案 20 :(得分:1)
你应该始终最大限度地优化,性能总是很重要。我们今天拥有英国媒体报道的原因是大多数程序员不想做优化工作。
话虽如此,你总是可以在光滑的编码需要澄清的地方发表评论。
答案 21 :(得分:1)
可读性是第一目标。
在1970年代,军队测试了一些当时的“新”软件开发技术(自上而下的设计,结构化编程,主要程序员团队,仅举几例),以确定哪些技术在统计上有显着差异。
只有在发展方面取得统计上显着差异的技术才是......
添加BLANK LINES以编写代码。
这些预先构建的,面向对象前的代码中可读性的提高是这些研究中提高生产率的唯一技术。
==============
只有在整个项目经过单元测试并准备好进行检测时,才能解决优化问题。您永远不知道在哪里需要优化代码。
在其具有里程碑意义的书籍中,Kernigan和Plauger在1970年代后期的软件工具(1976年)和软件工具在PASCAL(1981年)中展示了使用自顶向下设计创建结构化程序的方法。他们创建了文本处理程序:编辑器,搜索工具,代码预处理器。
在已完成的文本格式化函数INSTRUMENTED他们发现大部分的处理时间是进行文字输入和输出(在原书三个例程中度过的,在IO功能把89%的时间。在帕斯卡书,这些功能消耗了55%!)
他们能够优化这三个例程,并通过合理,可管理的开发时间和成本产生更高性能的结果。
答案 22 :(得分:1)
可读性优先。但是,就数据结构而言,可读性甚至超过简单性,尤其。
我想起了一个学生正在做一个视力分析计划,他无法理解为什么这么慢。他只是遵循良好的编程习惯 - 每个像素都是一个对象,它通过向邻居发送消息来起作用......
检查出来
答案 23 :(得分:1)
这取决于需要解决的任务。通常可读性更重要,但是当你首先考虑性能时,仍然有一些任务。在一切工作完美之后,您不能只花一天时间或进行分析和优化,因为优化本身可能需要从头开始重写代码的足够部分。但现在这种情况并不常见。
答案 24 :(得分:1)
比特移位与乘法是平凡优化, 旁边增益。并且,正如已经指出的,您的编译器应该为您做到这一点。除此之外,无论如何,增益都可以忽略,就像这条指令运行的CPU一样。
另一方面,如果您需要执行严格的计算,则需要正确的数据结构。但是,如果您的问题很复杂,那么找出解决方案就是解决方案的一部分。 作为示例,请考虑在1000000个未排序对象的数组中搜索ID号。然后使用二叉树或哈希映射重新考虑。
但是优化如n&lt;&lt; C通常是可以忽略的,并且在任何时候都无法改变。使代码不可读。
答案 25 :(得分:1)
如果没有可读性,当您真正需要时,很难获得性能提升。
性能应该只在程序出现问题时才能得到改善,有很多地方可能是瓶颈,而不是这种语法。假设你在&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;但忽略了10分钟的IO时间。
此外,关于可读性,专业程序员应该能够阅读/理解计算机科学术语。例如,我们可以将方法命名为enqueue,而不是说putThisJobInWorkQueue。
答案 26 :(得分:0)
我想说的是可读性。
但是在给定的例子中,我认为第二个版本已经足够可读,因为函数的名称确切地说明了函数中发生了什么。
如果我们总是有功能告诉我们,他们做了什么......
答案 27 :(得分:0)
“表现总是很重要”不是真的。如果你受I / O限制,那么乘法速度无关紧要。
有人说“我们今天拥有英国媒体报道软件的原因是,大多数程序员不想做优化工作”,这当然是正确的。我们有编制者来处理这些事情。
如果适合该架构,那么现在任何编译器都会将x*2
转换为x<<1
。这是编译器比编程器更聪明的情况。
答案 28 :(得分:0)
可读性。它将允许其他人(或您以后的某个时间)确定您要完成的任务。如果您以后发现需要担心性能,那么可读性将帮助您实现性能。
我还认为,通过专注于可读性,您实际上最终会得到更简单的代码,这些代码很可能比更复杂的代码实现更好的性能。
答案 29 :(得分:0)
绝大多数时候,我同意世界上大多数人的可读性 更重要。计算机速度比你想象的要快,而且速度越来越快,编译器会为你做微观优化,一旦你发现它们在哪里就可以优化瓶颈。
另一方面,有时,例如,如果您正在编写一个小程序,可以执行一些严重的数字运算或其他非交互式计算密集型任务,您可能需要做出一些高级设计决策考虑到绩效目标。如果你在这些情况下尝试稍后优化慢速部分,你基本上最终会重写大部分代码。例如,你可以尝试在小类等中很好地封装东西,但是如果性能是一个非常高的优先级,你可能不得不考虑一个不太精心设计的设计,例如,它不会执行尽可能多的内存分配
答案 30 :(得分:0)
优先级必须是可读性。然后是性能,如果它得到很好的评论,以便维护者知道为什么某些东西不标准。
答案 31 :(得分:0)
但是我不明白为什么代码无法读取并同时提供良好的性能。在您的示例中,第二个版本与第一个版本一样可读。什么不太可读?如果程序员不知道向左移动与乘以2的幂相同而向右移动就等于除以2的幂......那么,你有比一般可读性更基本的问题。 / p>
答案 32 :(得分:0)
一小时的处理器时间需要多少钱?
一个小时的程序员时间花了多少钱?
答案 33 :(得分:0)
首先编写可读性,但希望读者是程序员。任何值得他或她的盐的程序员应该知道乘法和位移之间的区别,或者能够读取适当使用它的三元运算符,能够查找并理解复杂的算法(你正在评论你的代码吗? )等等。
当然,早期的过度优化很难让您在以后需要重构时遇到麻烦,但这并不适用于单个方法,代码块或语句的优化。答案 34 :(得分:-3)
如果您要发布您的软件,您必须关心结果,而不是过程。
用户不会阅读您的代码,他们会使用您的软件,并且他们不希望因不必要的长时间等待而感到沮丧。如果你的缩进正确评论的应用程序运行缓慢或占用大量内存,他们会讨厌你。
简而言之,想想用户,而不是自己,所以更喜欢性能而不是可读性。
此规则的最佳示例之一是Quake视频游戏。它的代码结构不合理,通常难以读取,但它可以在1995-1996 PC上以非常高的帧速率渲染数千个多边形。 Quake以及许多其他视频游戏,包括Call of Duty(源自Quake 3引擎),如果Carmack更喜欢可读性而不是性能,则不会存在。