您是否认为值得在代码质量和可维护性方面取得一些成绩?我记得杰夫阿特伍德的一篇文章说硬件很便宜,开发人员不是。我想我想把它改为“硬件很便宜,时间不是。”
我注意到一个MVC项目我最近一直在努力,有时我会失去DAYS只是试图从我的应用程序中挤出一些额外的性能,我开始认为这是不值得的。我刚刚发现自己在设计ASP.NET MVC应用程序时遇到了麻烦。我喜欢IQueryable to death,因为它允许我附加到查询,所以我可以得到一些流利的代码来使用它。但是能够做这样的事情似乎在控制器/ BLL上增加了更多的责任。
那你觉得怎么样?在Web应用程序的情况下,你可以为可维护/更清洁的代码折衷一些性能吗?您是否认为过早地尝试优化您可以做的一切?因为我们已经看到你无法预测所有要求。
答案 0 :(得分:16)
答案 1 :(得分:12)
引用的第一部分几乎被遗忘了(它不会轻易说出来),因此许多缺乏经验的工程师在软件项目的设计阶段都没有考虑性能。这几乎总是一个致命的错误,因为后来由于基本的设计缺陷,设计糟糕的应用程序很难优化。同时,当性能瓶颈尚不清楚时,尝试通过巧妙的技巧来节省CPU周期毫无意义。
关于你的问题,我认为设计适当的应用程序旨在应对其特定的性能要求,不需要以不可维护或“不清洁”的方式编码。只有当发现这些性能瓶颈时(例如,您发现您的应用程序花费90%的时间花在10%的代码中),您可能需要考虑谨慎在少量代码中使用优化技巧,使其保持可维护和易于理解。
许多Web应用程序的优点在于可以使用各种缓存技术大幅提高性能。当您控制服务器环境时(并且,就像您说的那样,硬件很便宜),您可以确保从Web应用程序的常用部分缓存出来。如果使用抽象层,这实际上不会产生不可维护的代码。 Facebook是Web应用程序的一个很好的例子,它以其优势利用缓存(memcached)而闻名。
答案 2 :(得分:5)
我真的不相信这是一个/或者。如果您编写干净,简单的代码,只执行所有处理的次数,那么您将拥有一些性能最佳的代码。这真的很简单。
答案 3 :(得分:4)
明显的答案是取决于。如果你的应用程序足够慢以至于它会显着影响可用性,并且你有测量来证明你的优化实际上有帮助,那么牺牲可维护性可能是一个合理的权衡。另一方面,如果您没有测量或者应用程序不够慢以至于不足以损害可用性,那么请始终考虑可读性,可维护性和灵活性。这只是归结为过早优化是万恶之源。
注意:如果您知道性能对您的应用程序很重要,那么设计时算法和架构优化并不一定是坏事,但就您的问题而言,您显然似乎在谈论 micro - 优化,适用于上述情况。
此外,在您的具体情况下,如果您无法判断您的应用是否足够慢以致可用性受损,那么现在还为时过早。如果可以,那就不是。
答案 4 :(得分:2)
所有好的答案。速度和清洁代码之间的选择是错误的二分法。
我没有看到你的工作,但我看过别人,而且总是一样的故事:
“这还不够快。我认为问题出在XXX代码中。我想我会调整一下,看看是否有帮助。”
你没有知道问题存在。
你猜测。
永远不要根据猜测做任何事情。
(当然你永远不会这样做,不是吗?但大多数人都这样做。)
您可以对代码进行分析。
我最喜欢的方法是在它缓慢的时候暂停几次,然后问它到底在做什么。
人们通常不会猜到这一点。
答案 5 :(得分:2)
在谈论性能之前,你应该真正了解大O符号,你可以在任何关于算法或维基百科的书中查阅。
Big O符号表示函数需要多长时间。例如。从0到100的列表中有O(N)。无论你的数字有多高,O符号都保持不变。此函数具有线性运行时,无法以任何方式进行改进。
现在,如果您有一个从0到100运行的列表,并且对于该列表中的每个项目,您执行另一个从0到100运行的列表,则会得到O(N ^ 2),这是工作的两倍,运行时间比运行时差得多上)。
在编写必须具有良好性能的应用程序时,我们讨论如何用O表示法编写一个好的运行时。窗口是否使用< 0.1秒或> 1秒并不重要,如果它们使用相同的算法。
这意味着,你所做的几秒钟的剃须可能没有不同的O符号,所以你不是真的以任何方式优化你的代码 - 所以对你来说,在asp.net中编写MVC我建议你专注关于编写干净可读的代码:)
当您了解了O表示法时,您将能够知道要选择哪些算法(如何对列表进行排序,填充它们,检索数据),这种方式使用O表示法中的运行时间最短,并且这些知识可能会成为可能你的代码比剃掉代码的速度快得多,编写紧密的循环就可以了。
Makach ^^
答案 6 :(得分:1)
质量(意思是易读)和性能都不是最重要的 - 正确无误!
答案 7 :(得分:1)
在某种程度上同意这一点。开发人员的时间成本很高,分析和优化代码是一种非常昂贵的方式,可能不会获得很大的性能提升。说完这取决于你正在使用的应用程序类型和环境。
如果您正在处理Web应用程序,那么您可以通过修复一些简单问题(主要在客户端)来进行大量改进。通过连接CSS / JS文件来减少HTTP请求,构建图像精灵等等,与实际分析代码相比,可以获得巨大的收益,并且非常好地利用了开发人员的时间。
我不知道我同意'硬件比开发商便宜'的报价。当然,硬件可以帮助您扩展应用程序并为其提供更多性能,但您要做的最后一件事就是依靠强大的硬件。如果您的软件与硬件紧密耦合,则在迁移到新数据中心,升级服务器等方面会失去很大的灵活性......从长远来看,没有这种灵活性可能会非常昂贵。假设您决定有效扩展应用程序的方法是迁移到Amazon的EC2基础架构。如果您的应用程序在每台服务器上需要 32GB的RAM,您将会发现这样的移动可能需要重写。
答案 8 :(得分:0)
我绝对重视自己的时间,而不是服务器端的 。如果我发现我的网站在数据库请求等方面表现不佳,那么升级服务器硬件是一种替代解决方案,可以(至少短期)解决我的问题,而无需查看代码。
但是,如果该应用非常 网络 ,我会花费相当多的时间来改善这一部分。发送大块数据会影响我的用户,无论我使用自己的服务器和上行链路做什么 - 如果他们不喜欢性能,他们就不会回来。
但正如其他几个人所说,这不是一个问题,而是在很大程度上取决于情况,性能问题有多重,应用程序在哪里等等。
答案 9 :(得分:0)
质量的标准定义是“符合客户期望(要求)”。如果您已经收集了良好的要求,那么您已同意某些性能标准。如果您的申请符合此标准,那么您就是在浪费您或客户的时间和金钱来做得更好。
编写松散耦合,内聚和易于阅读的代码只会降低与错误相关的风险和成本以及对需求的更改。如果您准备接受“泥球”编码的风险,那么请继续。我,我喜欢赚钱。
答案 10 :(得分:0)
好的设计经常牺牲一些性能来改进整个程序。例如,在层中编写代码会产生成本,但无论如何我们都会这样做,因为它可以使代码更容易长期更改。我们远程使用app服务器,不是因为它是最有效的方式,而是因为它可以扩展。
我从Code Complete 2回忆起,McConnell确实给出了一个例子,其中使得难以阅读的代码作为优化是必要的。该特定示例是加密算法。程序被制作成一种方法来消除调用函数的开销。所以,确实有一个时间和地点,但我相信它很少见。
至于解决性能问题,在大多数情况下,我发现性能问题与数据库/ IO相关或者是(内存泄漏)。正如其他人所建议的那样,分析是可行的方法,但追踪许多错误仍然很棘手。
至于硬件问题,硬件放松但不消除对优化代码的需求。更快的硬件实际上只允许我们使用不是最优的语言并做非常好的GUI内容。
答案 11 :(得分:0)
这是经典的权衡性能与可支持性之一。在编写COBOL结构化代码时(在20世纪80年代早期),我首先遇到了这种折衷。很明显,通过将所有内容分成可重用的模块,可以创建额外的分支和堆栈指针管理,并且在早期计算机上这会降低性能。答案是将函数组合在一起(并复制某些函数),以减少用于调用模块的代码交换和堆栈指针操作。这导致了可支持性问题。
继续前进,最近,我不得不对数据库进行反规范化,以创建可以缓存的大型对象。这里的问题是在CRM系统导航期间读取角色和职责的访问权限。长话短说,标准化版本花了太长时间来处理和加载每个屏幕所以30年后我仍然参与这个经典的交易。