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?
Performance refers to your software's responsiveness, stability, scalability, reliability, speed, and resource usage. The greater the software performance, the better your experience will be when you use the system.
Software performance engineering (SPE) aims to build predictable performance into systems by specifying and analyzing quantitative behavior from the very beginning of a system, through to its deployment and evolution.
Performance requirements define how well the software system accomplishes certain functions under specific conditions. Examples include the software's speed of response, throughput, execution time and storage capacity. The service levels comprising performance requirements are often based on supporting end-user tasks.
Good Design. Good design relies on a combination of high-level systems thinking and low-level component knowledge. In modern software design, best practice revolves around creating modular components that you can call and deploy as needed. In doing this, you build software that is reusable, extensible, and easy to test ...
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With