编写代码方法论的逐渐转变是否会影响系统性能?我应该在乎吗?


35

TD; DR:

关于我在问的问题有些困惑,所以这是问题背后的驱动思想:

我一直希望这个问题是什么。我本来可能说得不太好。但是其意图一直是“ 模块化,分离,松散耦合,解耦,重构的代码 ”,其本质明显比“ 整体式单一单元,在一个地方完成所有工作,一个文件,紧密耦合的 ”代码慢。剩下的只是我当时或现在或以后会遇到的细节和各种表现形式。在某种程度上,它肯定较慢。就像无碎片磁盘一样,您必须从任何地方拾起碎片。慢一点 当然。但是我应该在乎吗?

问题不在于...

与微优化,过早优化等无关。这与“优化这一部分或死亡”无关。

之后怎么样了?

它涉及随着时间而出现的有关编写代码的总体方法,技术和思考方式:

  • “将此代码作为依赖项注入到您的类中”
  • “每个班级写一个文件”
  • “将视图与数据库,控制器,域分开”。
  • 不要编写意大利面同质的单个代码块,而是编写可以协同工作的许多单独的模块化组件

它是关于在十年内当前在大多数框架中看到和倡导的代码的方式和样式,这些框架是在大会上倡导的,并且是通过社区传播的。这是思维方式从“整体块”到“微服务”的转变。随之而来的是机器级别的性能和开销,以及一些程序员级别的开销。

原始问题如下:

在计算机科学领域,我注意到编程方面的思维方式发生了显着变化。我经常遇到这样的建议:

  • 编写较小的函数式代码(这种方式更具可测试性和可维护性)
  • 将现有代码重构为越来越小的代码块,直到大多数方法/函数只有几行长并且很清楚它们的目的是什么(与更大的整体块相比,它创建了更多函数)
  • 编写只做一件事的函数-关注点分离等(通常会在堆栈上创建更多函数和更多帧)
  • 创建更多文件(每个文件一个类,用于分解目的的更多类,用于诸如MVC,域架构,设计模式,OO等层的目的,这会创建更多文件系统调用)

与“旧”或“过时”或“意大利面条”编码实践相比,这是一个变化,在常规编码实践中,您的方法跨越2500行,并且大型类和上帝对象可以完成所有工作。

我的问题是这样的:

当涉及到机器代码,1和0,汇编指令以及HDD盘片时,我应该完全担心我的类完全分离的OO代码以及各种重构的小型函数和方法也会生成额外的开销?

细节

尽管我对ASM到底如何处理OO代码及其方法调用以及DB调用和编译器调用如何转换为在HDD磁盘上移动执行器臂的方式并不太熟悉,但我确实有一些想法。我假设每个额外的函数调用,对象调用或“ #include”调用(在某些语言中)都会生成一组额外的指令,从而增加代码量并增加各种“代码接线”开销,而无需添加实际的“有用”代码。我还认为可以在ASM实际上在硬件上运行之前对其进行良好的优化,但是优化也只能做很多事情。

因此,我的问题是-与“包含一个大方法,其中包含一个大方法一切都放在一个整体文件中”,由于这种开销?

为清楚起见,更新:

我假设采用相同的代码并将其拆分,重构,解耦为越来越多的函数,对象以及方法和类将导致越来越多的参数在较小的代码段之间传递。因为可以肯定的是,重构代码必须保持线程运行,并且这需要传递参数。与单个整体类或方法相比,更多的方法,更多的类或更多的Factory Method设计模式导致传递更多信息位的开销更大

有人说(引用待定),所有代码中多达70%是由ASM的MOV指令组成的-向CPU寄存器加载适当的变量,而不是进行实际的计算。就我而言,您可以使用PUSH / POP指令来加载CPU时间,以提供各种代码之间的链接和参数传递。您编写的代码段越小,所需的“链接”开销就越大。我担心这种联系会增加软件的膨胀和减慢速度,我想知道我是否应该关注这一点,以及是否要关注(如果有的话),因为现在和将来的下一代程序员都在为下个世纪构建软件,则必须使用和使用使用这些做法构建的软件。

更新:多个文件

我现在正在编写新代码,正在逐渐替换旧代码。特别是我注意到旧的类之一是〜3000行文件(如前所述)。现在,它已成为位于各个目录中的15-20个文件的集合,包括测试文件,不包括我用来将某些东西绑定在一起的PHP框架。还有更多文件。对于磁盘I / O,加载多个文件比加载一个大文件要慢。当然,并非所有文件都已加载,它们是根据需要加载的,并且存在磁盘缓存和内存缓存选项,但我仍然相信,这loading multiple files需要比loading a single file内存更多的处理工作。我将其添加到我的关注中。

更新:依赖注入所有内容

过一会儿再说。我认为我的问题被误解了。也许我选择误解了一些答案。我并不是在谈论微优化,因为一些答案已经被挑出来了(至少我认为我所说的关于微优化的说法是用词不当),而是整体上“重构代码以放松紧密耦合”的动向。 ,在代码的每个级别。我是最近从Zend Con来的,这种风格的代码一直是公约的核心和核心内容之一。从视图中解耦逻辑,从模型中解脱视图,从数据库中解脱模型,并且如果可能的话,从数据库中解耦数据。依赖-注入所有内容,有时意味着只添加什么都不做的接线代码(函数,类,样板),但可以用作接缝/勾点,在大多数情况下,很容易使代码大小加倍。

更新2:“将代码分成更多文件”是否会严重影响性能(在所有计算级别上)

哲学如何compartmentalize your code into multiple files影响当今的计算(性能,磁盘利用率,内存管理,CPU处理任务)?

我在说

之前...

在一个假设但还不算太远的过去中,您可以轻松地编写一个文件的单个块,该文件具有模型,视图和控制器意大利面条或未意大利面条编码,但是一旦加载完成就可以运行所有文件。过去使用C代码进行一些基准测试时,我发现将单个900Mb文件加载到内存中并进行大块处理要比加载一堆较小的文件并以较小的和平处理速度更快。最后进行相同的工作。

.. 现在*

今天,我发现自己正在查看显示分类账的代码,该代码具有..如果某项是“订单”等功能,则显示订单HTML块。如果可以复制订单项,请打印HTML块,该块后面显示一个图标和HTML参数,使您可以进行复制。如果可以向上或向下移动项目,则显示适当的HTML箭头。等等,我可以通过Zend Framework创建partial()调用,这实际上意味着“调用一个将参数带入其也会调用的单独HTML文件中的函数”。根据我想获得的详细程度,我可以为分类帐的最细部分创建单独的HTML函数。一个用于向上箭头,向下箭头,一个用于“我可以复制此项目”,等等。轻松创建多个文件只是为了显示网页的一小部分。以我的代码和幕后的Zend Framework代码为例,系统/堆栈可能会调用近20-30个不同的文件。

什么?

我对某些方面感兴趣,这是通过将代码划分为许多较小的单独文件而造成的机器磨损

例如,加载更多文件意味着使它们位于文件系统的各个位置以及物理HDD的各个位置,这意味着需要更多的HDD查找和读取时间。

对于CPU,这可能意味着更多的上下文切换和加载各种寄存器。

在此子块中(更新#2),我更严格地关注如何使用多个文件来完成可以在单个文件中完成的相同任务,从而影响系统性能。

使用Zend Form API与简单HTML

我将Zend Form API与最新和最好的现代OO实践一起使用,以构建具有验证的HTML表单,并将其转换POST为域对象。

我花了35个文件才做到。

35 files = 
    = 10 fieldsets x {programmatic fieldset + fieldset manager + view template} 
    + a few supporting files

所有这些都可以用一些简单的HTML + PHP + JS + CSS文件替换,也许总共是4个轻量级文件。

是不是更好?这值得吗?...想象一下,加载35个文件+众多使它们工作的Zend Zramework库文件,而不是4个简单文件。


1
很棒的问题。我将进行一些基准测试(花一天左右的时间才能找到一些好的案例)。但是,这种程度的速度提高会增加可读性和开发成本。我最初的猜测是,结果是微不足道的性能提升。
丹·萨宾2014年

7
@Dan:请您将其放入日历中,以便在维护1年,5年和10年后对代码进行基准测试。如果我记得,我会再检查一下结果:)
mattnz 2014年

1
是的,这才是真正的踢脚。我认为我们都同意减少查找和函数调用的速度。但是我无法想象这样一种情况,它比诸如维护和轻松培训新团队成员之类的事情更受欢迎。
丹·萨宾2014年

2
为了澄清您对项目有特定的速度要求。还是只想让代码“更快”!如果是后者,我不会担心,那么速度足够快但易于维护的代码远比速度足够快但混乱的代码好得多。
Cormac Mulhall 2014年

4
避免出于性能原因而调用函数的想法正是Dijkstra在他关于过早优化的著名语录中所指责的那种疯狂的想法。说真的,我做不到
RibaldEddie 2014年

Answers:


10

我的问题是这样的:当它的调用归结为机器代码,1和0,汇编指令时,我是否应该担心我的类分隔代码以及各种小型函数会产生过多的额外开销?

我的回答是,应该。不是因为您有很多小功能(一次调用函数的开销相当大,并且可以通过在循环中进行一百万次小调用来减慢程序速度,但是今天编译器会为您内联它们,剩下的就用了)无需担心CPU花式预测算法,因此不必担心),但因为当功能太小而无法理智地使用大脑时,您将在程序中引入过多分层的概念。如果您有较大的组件,则可以合理地确定它们不会一遍又一遍地执行相同的工作,但是可以使您的程序过于精细,以至于您可能无法真正理解调用路径,最终会遇到一些麻烦那几乎行不通(而且几乎无法维护)。

例如,我在一个向我展示了一种方法的Web服务参考项目的地方工作。该项目包含32个.cs文件-单个Web服务!我认为这太复杂了,尽管每个部分都很小而且本身很容易理解,但在描述整个系统时,我很快发现自己不得不通过调用来跟踪,以了解它到底在做什么(有如您所料,涉及的抽象过多。我的替代Web服务是4个.cs文件。

我没有衡量性能,因为我认为它总体上几乎是相同的,但是我可以保证我的维护成本要便宜得多。当每个人都在谈论程序员时间比CPU时间更重要时,然后创建复杂的怪兽,这些怪物在开发和维护上都花费了大量的程序员时间,因此您不得不怀疑他们是否在为不良行为找借口。

有人说(引用待定),所有代码中多达70%是由ASM的MOV指令组成的-向CPU寄存器加载适当的变量,而不是进行实际的计算。

CPU的工作,它们将位从内存移到寄存器,进行加法或减法,然后再将其放回内存。所有的计算都可以归结为这一点。请注意,我曾经有一个非常多线程的程序,它花费了大部分时间进行上下文切换(即保存和还原线程的寄存器状态),而不是处理线程代码。在错误的位置上简单地锁住,确实会破坏那里的性能,这也是如此无害的代码。

因此,我的建议是:在两个极端之间找到一个明智的中间点,使您的代码对其他人看起来不错,并测试系统以查看其性能是否良好。使用操作系统功能来确保其在CPU,内存,磁盘和网络IO上的运行符合预期。


我认为这现在对我说的最多。它向我建议,一个很好的中间立场是从思维导图概念开始编写代码,同时遵循并使用某些概念(例如DI),而不是与深奥的代码分解和烦恼(即,DI不论您是否需要)捆绑在一起还是不行)。
丹尼斯

1
就我个人而言,我发现更多的“现代”代码在某种程度上更易于配置...我猜代码的可维护性越高,它的配置也就越容易,但是存在一个局限性,即把东西分成几小段使它们成为可能。少维护...
AK_15年

25

如果没有特别注意,诸如此类的微优化会导致代码无法维护。

最初看起来是个好主意,探查器告诉您代码更快,并且V&V / Test / QA甚至说可行。很快发现了错误,要求进行需求变更和从未考虑过的增强。

在项目的整个生命周期中,代码会降级并降低效率。可维护的代码将比不可维护的代码效率更高,因为它的降级速度较慢。原因是代码随着更改而建立了熵-

不可维护的代码很快就会具有更多的死代码,冗余路径和重复项。这会导致更多的错误,从而导致代码降级的周期-包括其性能。不久之后,开发人员对所做的更改是正确的信心不足。这会减慢它们的速度,使其保持谨慎状态,并且通常会导致甚至更多的熵,因为它们只处理可以看到的细节。

具有小模块和单元测试的可维护代码易于更改,不再需要的代码易于识别和删除。损坏的代码也更容易识别,可以放心地修复或替换。

SO最终归结为生命周期管理,而不是像“这更快,因此它总是会更快”那样简单。

最重要的是,慢速正确代码比快速错误代码无限快。


谢谢。为了将其推向前进的方向,我并不是在谈论微优化,而是在全球范围内着手编写更小的代码,并结合了更多的依赖注入,因此引入了更多的外部功能块,并且通常增加了代码的“移动部分”所有这些都需要连接在一起才能正常工作。我倾向于认为这会在硬件级别上产生更多的链接/连接器/变量传递/ MOV / PUSH / POP / CALL / JMP绒毛。我也确实看到了向代码可读性转变的价值,尽管以牺牲“绒毛”的硬件级计算周期为代价。
丹尼斯

10
出于性能考虑,避免函数调用绝对是微优化!说真的 我想不出更好的微优化示例。您有什么证据表明性能差异实际上与所编写的软件类型有关?听起来您没有任何东西。
RibaldEddie

17

据我所知,正如您使用内联指出的那样,在C ++等较低级别的代码形式上可以有所作为,但我可以轻松地说一下。

该网站进行了总结- 没有简单的答案。它取决于系统,取决于您的应用程序在做什么,取决于语言,取决于编译器和优化。

以C ++为例,内联可以提高性能。很多时候它可能无能为力,或者可能降低性能,但我个人从未听说过故事。内联只不过是建议编译器进行优化,这可以忽略。

如果您正在开发更高级别的程序,那么从一开始就根本不用担心开销。如今,编译器非常聪明,无论如何应该处理这些东西。许多程序员都有赖以生存的代码:永远不要相信编译器。如果这适用于您,那么即使您觉得很重要的微小优化也可能是重要的。但是请记住,每种语言在这方面都不同。Java在运行时自动进行内联优化。在Javascript中,网页的内联(而不是单独的文件)是一个提升,网页的每一毫秒都可能很重要,但这更多的是IO问题。

但是,在程序员可能正在做大量机器代码以及C ++之类的低级程序的情况下,窃听可能会产生很大的不同。游戏是CPU流水至关重要的一个很好的例子,尤其是在控制台上,内联之类的东西到处都是。

专门在线阅读:http : //www.gotw.ca/gotw/033.htm


从我的问题的角度来看,我不那么关注每行的内联,而是关注占用CPU,总线和I / O的时间过程以链接各种代码的“编码连线”。我想知道是否有某个地方有50%或更多的布线代码和50%的实际代码要运行。我想即使在一个人可以编写的最严格的代码中也有很多毛病,这似乎是事实。在位和字节级别上运行的许多实际代码都是物流-将值从一个位置移动到另一个位置,跳到一个位置或另一个位置,并且有时仅做加法
Dennis

...减法或其他与业务相关的功能。就像循环展开(由于为变量增加分配的开销较少)可以加速某些循环一样,编写较大的函数可能可以提高速度,只要为此设置了用例即可。我在这里的关注是更全面的,看到很多建议来编写更小的代码段,增加这种连接,同时有利于增加可读性(希望如此),并且以微不足道的代价为代价。
丹尼斯

3
@Dennis-要考虑的一件事是,在OO语言中,程序员编写的内容(a + b)与生成的代码之间几乎没有什么关联(简单地添加两个寄存器?首先从内存中移出吗?然后函数调用对象的operator +?)。因此,程序员级别的“小功能”一旦翻译成机器代码,可能就很小了。
迈克尔·科恩

2
@Dennis我可以说,为Windows编写ASM代码(直接而不是编译)遵循“ mov,mov,invoke,mov,mov,invoke”的原则。通过invoke是一个宏,它可以执行由push / pops包装的调用...有时,您将使用自己的代码进行函数调用,但与所有OS调用相比,它显得微不足道。
Brian Knoblauch 2014年

12

与“旧的”或“不良的”代码实践相比,这是一个变化,在常规实践中,您的方法跨越2500行,而大型类则可以完成所有工作。

我认为没有人认为这样做是一种好习惯。而且我怀疑这样做的人是出于性能原因。

我认为Donald Knuth的名言在这里非常相关:

我们应该忘记效率低下的问题,例如大约97%的时间:过早的优化是万恶之源。

因此,在您的97%的代码中,只需使用良好的做法,编写小的方法(考虑到很小的问题,我认为所有方法都不应该只有几行),等等。对于其余3%的代码,性能确实很重要,请对其进行衡量。并且,如果测量结果表明拥有许多小方法实际上会极大地降低代码速度,那么您应该将它们组合成更大的方法。但是不要仅仅因为它可能更快而编写无法维护的代码。


11

您需要注意听取经验丰富的程序员以及当前的想法。与大型软件打交道多年的人可以有所作为。

以我的经验,这是导致速度下降的原因,而且幅度不小。它们是数量级:

  • 假设任何代码行大约需要与其他代码一样多的时间。例如cout << endla = b + c。前者的时间是后者的数千倍。Stackexchange有很多形式为“我尝试了优化此代码的方式,但似乎没有什么不同,为什么不这样做?”的问题。当中间有一个古老的函数调用时。

  • 当然,必须假设任何函数或方法调用一旦编写就可以。函数和方法易于调用,并且调用通常非常有效。问题在于它们就像信用卡一样。他们诱使您花费比您真正想要的更多的钱,而且他们倾向于隐藏您的花费。最重要的是,大型软件在抽象的每一层都有一层,因此,即使每层只有15%的浪费,在5层以上的复合速度减慢因子为2。答案是不删除功能或编写更大的功能是要训练自己,以防患于未然,并乐于并有能力根除此问题

  • 疾驰的普遍性。抽象的价值在于它可以让您用更少的代码来做更多的事情-至少那是希望。这个想法可以推到极致。过于笼统的问题是每个问题都是特定的,当您使用通用抽象来解决它时,这些抽象不一定能够利用问题的特定属性。例如,我看到一种情况,当长度不超过3时,就使用了一个花哨的优先级队列类,该类在大尺寸时可能会很有效!

  • 舞动的数据结构。OOP是一种非常有用的范例,但是它并不鼓励人们最小化数据结构,而是鼓励人们试图掩盖其复杂性。例如,存在“通知”的概念,其中,如果以某种方式修改了基准A,则A发出通知事件,以便B和C也可以自行修改,以使整个集合保持一致。这可以传播到许多层,并且极大地增加了修改的成本。那么完全有可能撤消对A的更改或更改为另一种修改,这意味着必须再次努力保持集合的一致性。令人困惑的是,所有这些通知处理程序中都存在错误的可能性以及循环性等。尝试保持数据结构规范化要好得多,这样,只需在一个地方进行任何更改即可。如果无法避免非规范化数据,则最好定期进行修复以解决不一致问题,而不是假装可以保持短暂的一致性。

...当我想到更多时,我将其添加。


8

简短的回答是“是”。而且,通常,代码会慢一些。

但是,有时适当的面向对象的重构将揭示出使代码更快的优化。我从事的一个项目中,我们使用了适当的数据结构,吸气剂等,而不是凌乱的对象嵌套数组,使复杂的Java算法变得更加面向对象。但是,通过更好地隔离和限制对数据结构的访问,我们能够从巨大的Doubles数组(以null表示空结果)更改为更有条理的Doubles数组,以NaN表示空结果。速度提高了10倍。

附录:通常,较小,结构更好的代码应更适合多线程,这是获得主要加速的最佳方法。


1
我不明白为什么从Doubles 切换到doubles需要更好的结构化代码。
2013年

哇,不赞成投票吗?原始客户端代码没有处理Double.NaNs,但是正在检查是否有null代表空值。重组之后,我们可以使用各种算法结果的getter处理(通过封装)。当然,我们可以重写客户端代码,但这更容易。
user949300 2014年

记录下来,我不是那个否定答案的人。
2013年

7

除其他外,编程与权衡有关。基于这个事实,我倾向于回答“是”,这可能会更慢。但是想想你得到的回报。变得易读,可重用和易于修改的代码很容易克服所有可能的缺点。

正如@ user949300所提到的,使用这种方法更容易发现可以在算法或体系结构上进行改进的区域。改善这些功能通常比没有可能的 OO或函数调用开销(我敢打赌,这已经只是一种噪音)更为有益和有效。


我还认为可以在ASM实际上在硬件上运行之前对其进行良好的优化。

每当我想到这样的事情时,我都记得,最聪明的人花数十年时间从事编译器工作,可能使GCC之类的工具在生成机器代码方面比我好得多。除非您正在从事与微控制器相关的某种工作,否则我建议您不要担心。

我假设在代码中添加越来越多的功能以及越来越多的对象和类将导致越来越多的参数在较小的代码段之间传递。

假设优化时做任何事情都是浪费时间,那么您需要有关代码性能的事实。使用专用工具查找您的程序大部分时间都花在哪里,然后对其进行优化和迭代。


总结一下;让编译器执行其工作,专注于重要的事情,例如改进算法和数据结构。您在问题中提到的所有模式都可以帮助您使用它们。

PS:这2条Crockford的演讲突然出现在我的脑海中,我认为它们之间有些相关。第一个是超级简短的CS历史(对于任何一门精确的科学,总是很了解)。第二个是为什么我们拒绝好东西。


我最喜欢这个答案。人们在second测编译器并在瓶颈所在处开枪,这真是太可怕了。当然,您应该意识到big-O的时间复杂性,但是100行大型意大利面条方法与工厂方法调用+某些虚拟方法分派甚至都不应成为讨论。在那种情况下,性能一点也不有趣。此外,还有一个很大的优势,即注意到没有确凿的事实和度量进行“优化”是浪费时间。
萨拉

4

我相信您所确定的趋势指向开发软件的事实-程序员的时间比CPU的时间贵。到目前为止,计算机变得越来越便宜,但是,混乱的应用程序可能需要数百甚至数千个工时才能进行更改。考虑到薪水,福利,办公空间等的成本,使代码的执行速度稍慢一些,但更改更快,更安全,则更具成本效益。


1
我同意,但是移动设备变得如此流行,以至于我认为它们是一个很大的例外。尽管处理能力在提高,但是您无法构建iPhone应用程序,并且期望能够像在Web服务器上那样添加内存。
JeffO

3
@JeffO:我不同意-具有四核处理器的移动设备现在是正常的,但性能(尤其是它会影响电池寿命)却不如稳定性重要。速度较慢的手机或平板电脑的评论不佳,不稳定的手机或平板电脑会被屠杀。移动应用程序非常动态,几乎每天都在变化-来源必须跟上。
mattnz

1
@JeffO:就其价值而言,Android上使用的虚拟机非常糟糕。根据基准测试,它可能比本机代码慢一个数量级(而同类最佳产品通常只是慢一点)。猜猜是什么,没人在乎。编写应用程序的速度很快,CPU坐在那里摇晃它的拇指,无论如何都要等待90%的用户输入时间。
Jan Hudec

性能不仅仅是原始的CPU基准。我的Android手机工作正常,除非AV正在扫描更新,然后挂起的时间比我喜欢的时间长,并且它是四核2Gb RAM型号!如今,带宽(无论是网络还是内存)可能是主要瓶颈。您的超高速CPU可能有99%的时间在摇动手指,总体体验仍然很差。
gbjbaanb 2014年

4

好在20年前,我猜您不是在称新的,也不是“旧的或坏的”,其规则是保持功能足够小以适合打印页面。然后我们有了点矩阵打印机,因此行数通常是固定的,每页行数通常只有一两个选择……绝对少于2500行。

您在询问问题的许多方面,即可维护性,性能,可测试性和可读性。您越倾向于性能,代码将变得越难维护和可读性,因此您必须找到自己的舒适度,并且该舒适度可能会因每个程序员而有所不同。

对于由编译器生成的代码(如果需要的话,将是机器代码),函数越大,需要将寄存器中的中间值溢出到堆栈的机会就越大。使用堆栈帧时,堆栈消耗量较大。函数越小,数据保留在寄存器中的机会就越大,并且对堆栈的依赖性越小。每个函数自然需要较小的堆栈块。堆栈框架在性能方面有优缺点。更多的较小功能意味着更多的功能设置和清除。当然,这还取决于您的编译方式,给编译器带来的机会。您可能有250个10行函数,而不是一个2500行函数,如果编译器可以/选择在整个过程中进行优化,则将获得一个2500行函数。但是,如果采用这250个10行函数并将它们分布在2、3、4、250个单独的文件中,分别编译每个文件,则编译器将无法优化出尽可能多的死代码。最重要的是,两者都有利弊,因此不可能对此设置通用规则,否则这是最好的方法。

人们可以在屏幕或页面上看到的合理大小的功能(以合理的字体)是比很大的代码可以更好地理解的功能。但是,如果这只是一个调用了许多其他小功能的小功能而又调用了许多其他小功能,则您需要安装多个Windows或浏览器来理解该代码,因此您不会在可读性方面买任何东西。

unix的方法是使用我所说的术语,将乐高积木打磨得很好。在我们停止使用磁带后的多年里,为什么还要使用磁带功能?因为Blob在后台非常出色地完成了工作,所以我们可以用文件接口替换磁带接口,并利用程序的功能。为什么仅仅因为scsi被ide取代了主导接口而重新编写cdrom刻录软件,然后再写回来。再次利用抛光子模块的优势,并用新的接口模块代替一端(也了解硬件设计人员只是在硬件设计上添加了接口模块,在某些情况下使scsi驱动器具有scsi接口的含义。 ,建造合理尺寸的抛光乐高积木,每个积木都有明确的用途以及明确的输入和输出。您可以将测试包装在这些lego块周围,然后使用相同的块,并将用户界面和操作系统界面包装在相同的块和该块周围,从理论上讲,经过良好测试和充分理解的不需要调试,只需添加其他新块在每一端。只要您所有模块的接口都经过精心设计并且功能得到很好的理解,您就可以用最少的胶水来构建很多东西。就像已知大小和形状的蓝色,红色,黑色和黄色乐高积木一样,您可以做很多事情。只要您所有模块的接口都经过精心设计并且功能得到很好的理解,您就可以用最少的胶水来构建很多东西。就像已知大小和形状的蓝色,红色,黑色和黄色乐高积木一样,您可以做很多事情。只要您所有模块的接口都经过精心设计并且功能得到很好的理解,您就可以用最少的胶水来构建很多东西。就像已知大小和形状的蓝色,红色,黑色和黄色乐高积木一样,您可以做很多事情。

每个人都是不同的,他们对打磨,定义清晰,经过测试和可读性的定义各不相同。例如,由教授决定编程规则不是没有道理的,不是因为它们对您作为专业人士而言可能有害,也可能不会有害,但是在某些情况下,使教授或研究生助教更容易阅读和评分代码...在职业上,您同样有可能发现,由于各种原因,每项工作可能有不同的规则,通常一个或几个掌权者对某事是非是有自己的见解,并凭借这种力量可以指示您做某事在那里(或退出,被解雇或以某种方式上台)。这些规则经常基于意见,就像它们基于某种有关可读性,性能,可测试性,可移植性的事实一样。


“因此,您必须找到适合每个程序员的舒适水平,并且会有所不同”,我认为优化水平应该由每段代码的性能要求决定,而不是由每个程序员的喜好决定。
2013年

假定程序员已告诉编译器优化,则编译器肯定会编译器通常默认情况下未优化(在命令行上,如果使用,则IDE可能具有其他默认值)。但是程序员可能不了解优化函数的大小,并且对于尽可能多的目标,徒劳无益?手动调校性能倾向于对可读性产生负面影响,尤其是可维护性,可测试性可以任意选择。
old_timer 2014年

2

取决于编译器的智能程度。通常,试图超越优化器是一个坏主意,实际上可能会使编译器失去进行优化的机会。对于初学者而言,您可能一无所知,无论它能做什么,而实际上您所做的大部分事情也会影响它的执行效果。

过早的优化是程序员尝试执行此操作的想法,并最终导致难以维护的代码实际上不在他们尝试执行的关键路径上。例如,在我看到的很多情况下,尝试在大多数情况下实际上阻止应用程序等待IO事件时尝试尽可能多地挤出CPU。

最好的方法是编写正确性代码,并使用探查器查找实际的性能瓶颈,并通过分析关键路径上的内容以及是否可以改进这些内容来修复这些问题。通常,一些简单的修复方法会大有帮助。


0

[计算机时间元素]

对松耦合和较小功能的重构会影响代码速度吗?

是的,它确实。但是,由解释器,编译器和JIT编译器来精简此“接缝/接线”代码,有些则比其他的要好,但有些则没有。

多文件问题增加了I / O开销,因此(在计算机时间)对速度的影响也很大。

[人速元素]

(我应该注意吗?)

不,你不在乎。如今,计算机和电路的速度非常快,其他因素也占据了上风,例如网络延迟,数据库I / O和缓存。

因此,本机代码执行速度降低2倍至4倍本身常常会被其他因素淹没。

至于多文件加载,通常通过各种缓存解决方案来解决。第一次加载并合并它们可能需要更多时间,但是对于下一次,对于静态文件,缓存的工作方式就像加载单个文件一样。缓存是多文件加载的一种解决方案。


0

答案(以防万一您错过了它)

是的,您应该关心,但关心代码的编写方式,而不是性能。

简而言之

不在乎性能

在这个问题的背景下,更聪明的编译器和解释器已经解决了这个问题

注意编写可维护的代码

维护成本在合理的人工理解水平上的代码。也就是说,即使您了解每个函数,也不要编写1000个较小的函数,以使代码难以理解,不要编写1个太大而难以理解的上帝对象函数,而要编写10个对人类有意义的精心设计的函数,并且易于维护。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.