【问题标题】:Should a developer aim for readability or performance first? [closed]开发人员应该首先以可读性还是性能为目标? [关闭]
【发布时间】:2010-09-16 00:58:53
【问题描述】:

开发人员通常会在解决问题的两种可能方法之间做出选择——一种是惯用且易读的,另一种不太直观,但性能可能更好。例如,在基于 C 的语言中,有两种方法可以将数字乘以 2:

int SimpleMultiplyBy2(int x)
{
    return x * 2; 
}

int FastMultiplyBy2(int x)
{
    return x << 1;
}

第一个版本对于技术和非技术读者来说更容易上手,但第二个版本可能表现更好,因为位移比乘法更简单。 (现在,我们假设编译器的优化器不会检测到这一点并对其进行优化,尽管这也是一个考虑因素)。

作为开发人员,最初的尝试哪个更好?

【问题讨论】:

  • 有点苛刻。关于我们有时都有的担忧的好问题。 +1
  • 这个例子显然是做作和琐碎的。你不会真的有一个带有硬编码乘数的函数。
  • 重点是我看到很多问题,比如“
  • 这是我在 stackoverflow 上读到的最好的问题之一。这涉及到计算机如何操作的实质,而不仅仅是语言的语义。 +1
  • @OutlawLemur 我知道这一点。但是有些人会问,例如,使用

标签: performance readability


【解决方案1】:

可读性 100%

如果你的编译器不能为你做 "x*2" => "x

还请记住,您的程序 99.9% 的时间都花在等待用户输入、等待数据库查询和等待网络响应上。除非您进行多次 20 亿次,否则不会引起注意。

【讨论】:

    【解决方案2】:

    如果你要发布你的软件,你必须关心结果,而不是过程。

    用户不会阅读您的代码,他们会使用您的软件,并且他们不想因不必要的长时间等待而感到沮丧。如果您缩进并正确注释的应用程序运行缓慢或占用大量内存,他们会讨厌您。

    简而言之,考虑用户,而不是您自己,因此更注重性能而不是可读性。

    此规则的最佳示例之一是 Quake 视频游戏。它的代码结构不佳,通常难以阅读,但它可以在 1995-1996 年的 PC 上以非常高的帧速率渲染数千个多边形。如果 Carmack 更喜欢可读性而不是性能,那么 Quake 以及包括使命召唤(源自 Quake 3 引擎)在内的许多其他视频游戏就不会存在。

    【讨论】:

      【解决方案3】:

      如果没有可读性,那么当你真正需要它时,将很难获得性能提升。

      只有当你的程序出现问题时才应该提高性能,有很多地方会是瓶颈而不是这种语法。假设您在

      此外,关于可读性,专业程序员应该能够阅读/理解计算机科学术语。例如,我们可以将方法命名为 enqueue 而不必说 putThisJobInWorkQueue。

      【讨论】:

      • 虽然我同意,但我认为你的例子很糟糕。例如,作为一个对你的代码库一无所知的人,入队对我来说意义不大。我不想知道怎么做,我想知道什么。您给出的示例说明了更好的方法。
      【解决方案4】:

      可读性第一。但比可读性更重要的是简单性,尤其是在数据结构方面。

      我想起了一个做视觉分析程序的学生,他不明白为什么它这么慢。他只是遵循良好的编程习惯——每个像素都是一个对象,它通过向其邻居发送消息来工作......

      看看这个

      【讨论】:

        【解决方案5】:

        可读性是首要目标。

        在 1970 年代,军队测试了一些当时的“新”软件开发技术(自上而下的设计、结构化编程、首席程序员团队等),以确定其中哪些技术产生了显着的统计学差异。

        在开发过程中产生统计学显着差异的唯一技术是......

        在程序代码中添加空白行。

        在这些预结构化、预面向对象的代码中提高可读性是这些研究中提高生产力的唯一技术。

        ==============

        只有在整个项目经过单元测试并准备好进行检测时,才应进行优化。你永远不知道你需要在哪里优化代码。

        Kernigan 和 Plauger 在 1970 年代后期的 SOFTWARE TOOLS (1976) 和 SOFTWARE TOOLS IN PASCAL (1981) 的里程碑式著作中展示了使用自顶向下设计创建结构化程序的方法。他们创建了文本处理程序:编辑器、搜索工具、代码预处理器。

        当完成的文本格式化函数被 INSTRUMENTED 时,他们发现大部分处理时间都花在了执行文本输入和输出的三个例程中(在原书中,io 函数占用了 89% 的时间。在 pascal 书中,这些函数消耗了 55%!)

        他们能够优化这三个例程,并以合理、可管理的开发时间和成本提高性能。

        【讨论】:

          【解决方案6】:

          正如几乎每个人在回答中所说的那样,我赞成可读性。我运行的 100 个项目中有 99 个没有严格的响应时间要求,因此这是一个简单的选择。

          在开始编码之前,您应该已经知道答案。有些项目有一定的性能要求,比如“需要能够在 Y(毫秒)秒内运行任务 X”。如果是这种情况,您就有了一个要努力的目标,并且您知道何时必须进行优化。 (希望)这是在项目的需求阶段确定的,而不是在编写代码时。

          良好的可读性和后期优化的能力是正确软件设计的结果。如果您的软件设计合理,您应该能够隔离软件的某些部分并在需要时重写它们,而不会破坏系统的其他部分。此外,我遇到的大多数真正的优化案例(忽略一些真正的低级技巧,这些都是偶然的)都是从一种算法更改为另一种算法,或者将数据缓存到内存而不是磁盘/网络。

          【讨论】:

            【解决方案7】:

            我不在谷歌工作,所以我会选择邪恶的选择。 (优化)

            在 Jon Bentley 的“Programming Pearls”的第 6 章中,他描述了一个系统如何通过在 6 个不同的设计级别进行优化来实现 400 倍的加速。我相信,通过不关心这 6 个设计级别的性能,现代实现者可以轻松地在他们的程序中实现 2-3 个数量级的减速。

            【讨论】:

              【解决方案8】:

              你错过了一个。

              第一个代码是为了正确,然后是为了清楚起见(当然,这两者通常是相互关联的!)。最后,只有当你有真正需要的真实经验证据时,你才能考虑优化。过早的优化确实是邪恶的。优化几乎总是会花费您的时间、清晰度和可维护性。你最好确保你买的是有价值的东西。

              请注意,好的算法几乎总能击败本地化调优。您没有理由不能拥有正确、清晰和快速的代码。不过,如果您一开始就专注于“快速”,那您将非常幸运。

              【讨论】:

              • 这无疑是这里最好的答案。调整算法,而不是代码。通过细微的更改,我可以使 Erastosthenes 的 jscript Sieve 优于其他相同的 C++ 版本。 (不是阿特金斯筛,我自己的方法。)
              • 太糟糕了,你不能收藏回复。 :)
              【解决方案9】:

              据估计,大约 70% 的软件成本用于维护。可读性使系统更易于维护,从而降低了软件在其生命周期内的成本。

              在某些情况下,性能比可读性更重要,也就是说它们很少见。

              在牺牲可读性之前,想一想“我(或您的公司)是否准备好通过这样做来处理我给系统增加的额外成本?”

              【讨论】:

                【解决方案10】:

                “性能永远重要”是不正确的。如果您受 I/O 限制,则乘法速度无关紧要。

                有人说“我们今天有英国媒体报道软件的原因是大多数程序员不想做优化工作”,这当然是真的。我们有编译器来处理这些事情。

                如今,如果适合该架构,任何编译器都会将x*2 转换为x&lt;&lt;1。这是编译器比程序员更聪明的情况。

                【讨论】:

                  【解决方案11】:

                  可读性。它将允许其他人(或以后的您自己)确定您要完成的工作。如果您后来发现确实需要担心性能,那么可读性将帮助您实现性能。

                  我还认为,通过专注于可读性,您实际上会得到更简单的代码,这很可能会比更复杂的代码获得更好的性能。

                  【讨论】:

                    【解决方案12】:

                    在绝大多数情况下,我同意世界上大多数人的观点,即可读性非常更为重要。计算机比您想象的要快,而且只会越来越快,编译器会为您进行微优化,一旦您发现瓶颈在哪里,您就可以稍后对其进行优化。

                    另一方面,但有时,例如,如果您正在编写一个小程序,该程序将执行一些严重的数字运算或其他非交互式、计算密集型任务,您可能必须做出一些高级设计决策考虑到绩效目标。如果您稍后在这些情况下尝试优化慢速部分,您基本上最终会重写大部分代码。例如,您可以尝试将事物很好地封装在小类中,等等,但如果性能是一个非常高的优先级,您可能不得不满足于不那么好的设计,例如,不执行尽可能多的内存分配.

                    【讨论】:

                      【解决方案13】:

                      如果您不了解自己的瓶颈,那么优化就毫无意义。你可能已经让一个函数变得难以置信的高效(通常以某种程度的可读性为代价)只是发现那部分代码几乎没有运行过,或者它花费更多的时间访问磁盘或数据库,而不是你保存的小玩意。 所以在你有一些东西要衡量之前,你不能进行微优化,然后你最好从可读性开始。 但是,在设计整体架构时,您应该注意速度和可理解性,因为两者都会产生巨大的影响并且难以更改(取决于编码风格和方法)。

                      【讨论】:

                        【解决方案14】:

                        优先级必须是可读性。然后是性能,如果它得到很好的评论,以便维护人员知道为什么某些东西不标准。

                        【讨论】:

                          【解决方案15】:

                          我会首先考虑可读性。考虑到当今我们拥有的那种优化的语言和负载巨大的机器,我们以可读方式编写的大多数代码都会表现得不错。

                          在一些非常罕见的情况下,您很确定自己会遇到一些性能瓶颈(可能来自过去的一些糟糕经历),并且您设法找到了一些可以为您带来巨大性能优势的奇怪技巧,您可以去。但是您应该很好地注释该代码 sn-p,这将有助于使其更具可读性。

                          【讨论】:

                            【解决方案16】:

                            可读性。

                            为性能而编码有其自身的一系列挑战。 Joseph M. Newcomer 说well

                            只有在优化时才重要 很重要。当它重要时,它很重要 很多,但直到你知道它 很重要,不要浪费很多时间 正在做。即使你知道这很重要, 你需要知道重要的地方。 没有性能数据,您将无法 知道要优化什么,你就会 可能优化错了。

                            结果会晦涩难懂 写,难调试,难 维护不能解决你的代码 问题。因此它具有双重性 (a) 增加的缺点 软件开发和软件 维护成本,以及 (b) 没有 完全没有性能影响。

                            【讨论】:

                              【解决方案17】:

                              您应该始终最大限度地优化,性能始终很重要。我们今天有膨胀软件的原因是大多数程序员不想做优化工作。

                              话虽如此,但您始终可以将 cmets 放在需要澄清精巧编码的地方。

                              【讨论】:

                              • 我在一定程度上同意。我认为你不应该像原来的问题所说的那样进行微优化。您必须以一种最佳方式使用资源的方式来设计您的系统。在该领域可以获得更多性能。
                              • 我们今天确实有英国媒体报道软件,但我不怪它缺乏优化。我把它归咎于过度设计,用火箭筒拍苍蝇,在只需要划艇时建造远洋客轮。那当然是沉重的。
                              • 我同意你们两位的观点,即优化设计是第一要务。我还要说,同样的态度应该适用于软件工程过程的各个层面。如果你懒得在代码层面做优化,那你可能在设计的时候也有欠缺。
                              【解决方案18】:

                              恕我直言,这两件事都无关。您应该首先选择有效的代码,因为这比性能或阅读效果更重要。关于可读性:您的代码在任何情况下都应该始终是可读的。

                              但是,我不明白为什么代码不能同时具有良好的可读性和性能。在您的示例中,第二个版本对我来说与第一个版本一样可读。什么是可读性较差的?如果程序员不知道左移与乘以 2 的幂相同,而右移与除以 2 的幂相同……那么,与一般可读性相比,您遇到的基本问题要多得多。

                              【讨论】:

                                【解决方案19】:

                                一个小时的处理器时间成本是多少?

                                程序员一个小时的时间成本是多少?

                                【讨论】:

                                • 最终用户一小时的时间成本是多少?现在乘以用户数量。
                                • gbjbaanb:完全是我的想法。 Andy 的评论仅适用于最终用户永远不会看到的服务,即使这样也很难进行比较。
                                【解决方案20】:

                                两者兼而有之。您的代码应该平衡两者;可读性和性能。因为忽略其中任何一个都会影响项目的投资回报率,而归根结底,这对你的老板来说才是最重要的。

                                可读性差会导致可维护性降低,从而导致将更多资源用于维护,从而降低投资回报率。

                                糟糕的表现会导致投资和客户群减少,从而导致投资回报率降低。

                                【讨论】:

                                  【解决方案21】:

                                  我会说是为了可读性。

                                  但在给定的示例中,我认为第二个版本已经足够可读了,因为函数的名称准确地说明了函数中发生了什么。

                                  如果我们总是有函数告诉我们,他们做了什么......

                                  【讨论】:

                                    【解决方案22】:

                                    使用

                                    Premature optimization是万恶之源。

                                    适用,您应该首先使用更具可读性的版本。

                                    恕我直言,这条规则经常被误用作设计永远无法扩展或性能良好的软件的借口。

                                    【讨论】:

                                      【解决方案23】:

                                      如果您担心代码的可读性,请不要犹豫,添加评论以提醒自己这样做的目的和原因。

                                      【讨论】:

                                        【解决方案24】:

                                        这取决于需要解决的任务。通常可读性更重要,但是当你首先要考虑性能时,仍然有一些任务。而且你不能只花一天时间进行分析和优化,因为优化本身可能需要从头开始重写代码的足够部分。但是现在已经不常见了。

                                        【讨论】:

                                          【解决方案25】:

                                          位移与乘法是一种微不足道的优化,在没有旁边获得。而且,正如已经指出的那样,您的编译器应该为您执行此操作。除此之外,增益是可以忽略不计的,运行这条指令的 CPU 也是如此。

                                          另一方面,如果您需要执行严格的计算,则需要正确的数据结构。但是,如果您的问题很复杂,那么找出答案就是解决方案的一部分。 例如,考虑在 1000000 个未排序对象的数组中搜索 ID 号。然后重新考虑使用二叉树或哈希图。

                                          但是像 n

                                          【讨论】:

                                            【解决方案26】:

                                            答案取决于上下文。例如,在设备驱动程序编程或游戏开发中,第二种形式是可接受的习语。在商业应用程序中,没有那么多。

                                            最好的办法是查看代码(或类似的成功应用程序)以检查其他开发人员是如何做到的。

                                            【讨论】:

                                              【解决方案27】:

                                              首先为可读性而写作,但希望读者是程序员。任何称职的程序员都应该知道乘法和位移之间的区别,或者能够阅读适当使用的三元运算符,能够查找并理解复杂的算法(您在评论您的代码对吗? ) 等。

                                              当然,早期的过度优化在以后需要重构时会给您带来麻烦,但这并不真正适用于单个方法、代码块或语句的优化。

                                              【讨论】:

                                                【解决方案28】:

                                                在此处添加带有解释的评论将使其可读且快速。

                                                这真的取决于项目的类型,以及性能的重要性。如果您正在构建一个 3D 游戏,那么通常会有很多常见的优化需要在此过程中投入其中,并且没有理由不这样做(只是不要过早得意忘形)。但是,如果您正在做一些棘手的事情,请发表评论,以便任何看到它的人都知道您如何以及为什么会变得棘手。

                                                【讨论】:

                                                  【解决方案29】:

                                                  可读性肯定。除非有人抱怨,否则不要担心速度

                                                  【讨论】:

                                                    【解决方案30】:

                                                    在这场辩论中,一个经常被忽视的因素是程序员需要额外的时间来导航、理解和修改可读性较差的代码。考虑到程序员的时间每小时花费一百美元或更多,这是一个非常实际的成本。
                                                    这种直接的额外开发成本抵消了任何性能提升。

                                                    【讨论】:

                                                      猜你喜欢
                                                      • 1970-01-01
                                                      • 2010-11-08
                                                      • 1970-01-01
                                                      • 2012-09-15
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      • 2011-02-08
                                                      • 2010-10-03
                                                      • 1970-01-01
                                                      相关资源
                                                      最近更新 更多