软件设计时是否应该考虑性能?

发布于 2024-08-07 13:16:45 字数 487 浏览 4 评论 0原文

在考虑性能的情况下对组件或软件架构进行归零设计是否明智?我的意思是,设计/架构应该如何准备好在性能密集型环境中使用?

在设计组件时,我们是否应该遵循良好的面向对象原则并确保组件是“可扩展的”。这样,当我们遇到性能问题时,我们可以在这里稍微调整一下设计。尽管这样,我们经常会遇到性能问题,稍微调整一下软件可能没有帮助。

或者,我们是否应该提出一种设计,尽管很复杂,但可以使性能问题变得轻而易举。我们仍然需要调整软件,但调整通常非常简单,因为设计是以性能为导向的。

注意:在上面列出的两种情况下,我都没有尝试在遇到性能问题之前调整软件的性能。换个说法,软件的设计应该以性能为导向吗?

请不要回答我说这完全取决于软件预期运行的环境。原因是任何工业级软件的客户似乎总是想要越来越多的东西。您可能不会计划您的软件在性能密集型环境中持续运行,但如果必须这样做怎么办?当我们意识到这一点时,我们是否应该重新设计软件?

这个问题已经困扰我一周了,但我还没有答案。您对此有何看法?

Is it advisable to zero-in on design of a component or architecture of a software with performance in mind? What I mean is, how ready should the design/architecture be to used in a performance-intensive environment?

While designing components, should we just follow good OO principles and just ensure that the component is 'extendable'. This way we tweak the design a bit here and a bit there as and when we run into performance issues. Although this way, we would often land up in performance issues where tweaking software a little bit might not help.

Alternatively, should we come up with a design, although complex, makes performance issues a cakewalk. We would still need to tweak the software, but the tweaking is often very simple as the design is performance-oriented.

Note: In neither of the cases listed above am I trying to tune the performance of the software before running into performance issues. To re-phrase the question, should the design of the software be performance-oriented?

Please do not answer me saying that it all depends on the environment in which a software is expected to run. The reason being that clients of any industrial-grade software just seem to want more and more and more all the time. You may not plan your software to be constantly running in performance-intensive environments, but what if it has to? Should we then re-design the software when we sense that?

This question has been troubling me from a week and I don't have an answer yet. What is your take on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

幼儿园老大 2024-08-14 13:16:45

当我写这篇文章时,已经有两个人回复了 Knuth 关于过早优化的引用。我认为这有点误导。在我看来,其背后的想法以及关于该主题的许多建议背后的想法是,程序是算法的集合,如果它不够高效,我们可以确定哪个算法太慢并用某种算法替换它更好的。

这种事情就忽略了程序的互联性。这些算法都隐藏在一些 API 后面。虽然“愿景”是 API 背后的算法是不透明的并且可以与其他算法互换,但它忽略了 API 对其调用者施加的约束。我已经完成了相当多的网络编程,并且很容易通过设计根本无法高效工作的 API 来编写低效的软件,那么当您必须对正在使用的 API 进行根本性更改时,您会做什么? (例如,在网络编程中,要求调用者在内存中构建完整消息的 API 比允许流式传输数据的 API 更容易设计和实现。)

因此,不要相信简单而简洁的引用。您不应该为小事而烦恼(尤其是完全不用担心 70 年代的人所做的事情;编译器现在更加聪明),而是完全忽略性能问题,抱着“我们以后总是可以分析和改进事情”的态度如果需要的话”可能会将您带入死胡同,您必须进行大量的重新实现。

哦,我还建议不要“为可扩展性而设计”。做最简单、有效的事情,如果你后来发现你所拥有的东西的概括使事情变得更容易或更简单,那就去做吧。根据我的经验,进行不必要的通用设计只会导致组件更难使用,并且通常不太可扩展,因为初始设计实际上无法预见组件在一般情况下应该执行哪些操作以及如何。

When I'm writing this, two people have already replied with the Knuth quote on premature optimization. I think that's somewhat misleading. The thinking behind that, and behind much advice on this topic, seems to me to be that a program is a collection of algorithms, and if it is not efficient enough, we can determine which of the algorithms is too slow and replace that with something better.

This kind of thing ignores the interconnectedness of the program. The algorithms are all hidden behind some APIs. While the "vision" is that the algorithm behind the API is opaque and interchangeable with another, it ignores the constraints placed by the API on its caller. I've done a fair share of network programming, and there it is easy to write inefficient software by designing APIs that simply cannot work efficiently, so what do you do when you have to make fundamental changes to an API that's being used all over? (In network programming, an API that requires the caller to build a complete message in memory is easier to design and implement than one that allows streaming the data, for instance.)

So, don't fall for simplistic and pithy quotes. You shouldn't sweat the small stuff (and especially don't worry at all about the things that people in the 70s did; compilers are much smarter now) but completely ignoring performance issues with the attitude "We can always profile and improve things later if needed" can lead you to a dead end where you have to do significant reimplementation.

Oh, and I would also advise against "designing for extensibility". Do the simplest thing that works, and if you later find that generalization of something you have makes things easier or simpler, do it then. In my experience, going for a needlessly-general design just results in a harder-to-use component that often isn't really very extensible because the initial design couldn't actually foresee what kinds of things the component should do in the general case and how.

り繁华旳梦境 2024-08-14 13:16:45

项目的设计必须平​​衡可扩展性、可维护性、性能、交付时间等。

我尝试设计包+高级图表以实现可扩展性,然后设计低级图表以提高性能。

The design of a project must balance extendability, maintainability, performance, time-to-shipping and more.

I try to design the package+high-level diagrams for extendability, then design the low-level for performance.

半步萧音过轻尘 2024-08-14 13:16:45

我必须全心全意地支持jk的回答。

Knuth 的引言在现实生活中有些不适用,除了一些不涉及架构的小问题领域之外

举个例子,我最近不得不花费 3-4 个月的时间从头开始重新构建一个相当复杂的系统,因为最初的设计假设 100% 的数据将从数据库加载到一个块中。这样的情况持续了 3 年,直到数据集增长到原始设计者预期的 100 倍左右,系统开始在 2G 使用量时仅仅耗尽内存或严重崩溃之间交替。

现在,解决方案在概念上很简单 - 允许从数据库中批量检索数据。
这样做很聪明。但是,如果他们不厌其烦地考虑性能问题,那么在最初的设计阶段可能需要额外花费几周的时间,结果却变成了 3 个月的考验,因为每个小函数、对象和 API 以及整体架构都明确地编写为假设“100%数据就在那里”。

一般来说,任何数据量是性能问题且数据分块是主要可行解决方案的情况,分块必须预先设计

I must second jk's answer with all my heart.

Knuth's quote is somewhat in-applicable in real life outside some small domain of problems which don't involve architecting.

As an example, I recently had to spend 3-4 months re-architecting from scratch a fairly involved system because the original design assumed that 100% of data will be loaded in one chunk from database. Which was fine for 3 years until the data set grew to ~100x of what the original designer anticipated, and the system started to alternate between merely running out of memory at 2G usage or crashing horribly.

Now, the solution was conceptually simple - allow retrieval of data from DB in batches.
Doing so intelligently worked. But what could have been extra couple of weeks of work in the original design stage had they bothered to think about performance turned into 3 month ordeal because every little function, object and API as well as overall architecture were explicitly written to assume "100% of data is there".

In general, any situation where the volume of data is a performance concern and chunking of data is the main feasible solution, that chunking MUST be designed for beforehead.

谜兔 2024-08-14 13:16:45

我想说,只要您从一开始就不知道每一点性能都很重要,就应该遵循良好的面向对象原则。

一般来说,巨大的性能提升是通过算法优化而不是架构重组来实现的(只要架构遵循正常的最佳实践)。除了对性能要求最高的环境之外,通过选择难以使用的设计获得的性能增益通常在所有环境中都是无关紧要的,因此,如果从一开始就不需要绝对的顶级性能,请选择良好的 OO。

I would say go with good object oriented principles as long as you do not know from the beginning that every little bit of performance will matter.

The big performance gains are in general reached through algorithmic optimization and not restructuring of the architecture (as long as the architecture follows normal best practice). The kind of performance gains that you get from choosing a harder-to-work-with design is most often irrelevant in all but the most performance demanding environments, so if absolute top performance is not a requirement from the beginning, go with good OO.

迷路的信 2024-08-14 13:16:45

我想说,这就是经验丰富的软件工程师和软件新手的区别。

经验丰富的软件工程师应该始终牢记其设计的性能问题。

示例:当您的模块内有一个具有 O(n^3) 性能行为的算法并且可能会增加 n 时,可能会出现您的模块在某些情况下会变得非常慢的情况。

当然,也有很多差异。当内存数组上的复杂度为 O(n^3) 时,与磁盘操作上的复杂度为 O(n^2) 相比,问题可能要少一些。

因此,经验很重要,可以考虑这些事情并决定必须更改设计的哪些地方,或者稍后的调整可以使其更快而不会出现问题。

I would say, that this is what makes the difference of a experienced software engineer and a software-newbie.

An experienced software engineer should always keep in mind the performance issues of his design.

Example: When you have an algorithm with O(n^3) performance behaviour inside your module with possible increasing n, the situation can arise, that your module will become very slow in circumstances.

Of course, there are many differences. When you have O(n^3) on an in-memory array, it might be less problematic as an O(n^2) on a disk operation.

So, experience is important to think about those things and to decide where the design must be changed or where a later tweaking can make it faster without problems.

你怎么敢 2024-08-14 13:16:45

遵循 OOP 最佳实践、广泛使用设计模式、架构良好的软件是(或者原则上应该是)可维护性良好的。如今,低级优化很少能发挥真正的作用,CPU 和资源都相当过剩。

只是代码可重用、可维护和可扩展。在这样的良好环境下,进一步的底层优化的实际需求将很容易实现。只有在真正必要的时候,只有在真正需要解决这个问题的时候。

A well architected software that follows OOP best practices, makes wide use of design patterns is, or should by principle be, a well maintainable. Nowadays it is rare that low level optimizations have a real role, CPU and resources are quite overabundant.

Just code reusable, maintainable and scalable. Further real needs for low level optimization will be easily implemented in such a good environment. Only when really necessary, only when it is really the moment to take care of this issue.

终难愈 2024-08-14 13:16:45

您应该始终以效率而非低效率为目标,但不能以牺牲可维护性为代价。所以,是的,您应该尝试以效率为目标进行设计,但要警惕过早的优化。唐纳德·高德纳 (Donald Knuth) 最喜欢的一句话是:

“我们应该忘记小的效率,大约 97% 的情况下:过早的优化是万恶之源。”

You should always aim at efficiency over inefficiency, but not at the cost of maintainability. So yes, you should try to design for efficiency, but be wary of premature optimization. The favorite quote from Donald Knuth:

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

带刺的爱情 2024-08-14 13:16:45

几乎以“视情况而定”的方式,我认为您确实需要考虑您的要求是什么。如果最高优先级的要求之一是“必须能够维持某种疯狂水平的吞吐量/性能”,那么您如果不在整体架构和技术选择中预先规划和设计这一点,那就太疯狂了。

Almost in an "it depends" way, I think you really need to take into consideration what your requirements are. If one of the highest priority requirements is "must be able to to sustain some crazy level of throughput/performance" then you would be crazy not to plan and design for that up front in the overall architecture and technology selection.

昔梦 2024-08-14 13:16:45

我觉得有趣的是,只有米凯尔·奥诺提到了“要求”这个词。

虽然 Knuth 的引述是TRVTH,但这一切都归结于要求。可扩展性是其中之一吗?预期负载是多少?如果您的答案是“我不知道”,请询问。

如果这些是要求,请将负载测试添加到您的验收测试中。

您仍然希望设计可维护性。将性能考虑因素推迟到最后负责时刻,然后进行分析 - 不要猜测。微观优化是浪费公司的资金。

有时,负责的时刻发生得相当早;我不会设计一个所有数据都以 XML 文件形式存储在磁盘上的企业 CRM 系统。我要做就是抽象持久层。

最后,Kolibri 的评论是正确的 - 答案(像往常一样)是“视情况而定”。

编辑:在重新阅读时,我担心我违反了OP的限制“请不要回答我说这一切都取决于软件预期运行的环境”。不过,我坚持我的答案。如果(当)需求发生变化,简单的设计通常更容易修改。未声明的假设是我们提前知道需求将如何发生变化。该请求可能是“使其扩展一个数量级”或“允许在组织之间移动客户”。前者的架构可能会使后者更难以实施。

I find it interesting that only Mikael Auno mentioned the word "requirement."

While Knuth's quote is TRVTH, it all comes down to the requirements. Is scalability one of them? What is the expected load? If your answer is "I don't know," ask.

If these are requirements, add load testing to your acceptance tests.

You still want to design for maintainability. Defer performance considerations to the Last Responsible Moment, then profile - don't guess. Micro-optimization is a waste of the company's money.

Sometimes the responsible moment occurs fairly early; I'm not going to design an enterprise CRM system where all the data is stored as XML files on disk. What I am going to do is abstract the persistence layer.

In the end Kolibri's comment is correct - the answer (as usual) is "it depends."

EDIT: On re-reading, I'm afraid I violated the OP's constraint of "Please do not answer me saying that it all depends on the environment in which a software is expected to run." I stand by my answer, though. If (when) the requirements change, a simple design is generally easier to modify. The unstated assumption is that we know ahead of time how the requirements are going to change. The request may be "make it scale by an order of magnitude" or "permit moving a customer between organizations." Architecting for the former may make the latter more difficult to implement.

鹿! 2024-08-14 13:16:45

不要提前进行任何优化。但是架构对系统的潜在性能有巨大的影响。

我建议阅读以下书籍:发布它!:设计和部署生产就绪软件

Do not make any optimiyation in advance. But the ARCHITECTURE ha a huge impact on the potential performance of the system.

I sugges rading the following book: Release It!: Design and Deploy Production-Ready Software

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文