Slow systems and systems slowing down
We all know the call from a client telling you that the software has become so slow, it’s unusable. Yesterday it was fine, but today it is a disaster. It’s not that the code has a life of its own, but reaches a tipping point where performance degradation has eroded to the point of unresponsiveness.
Generally speaking, systems tend to get slower over time. Data sets grow, libraries get upgraded and code expands to fit business needs – one or all of these factors can influence the performance of a system.
What is performance optimisation?
Before we start, let us look at what is performance optimisation.
In a nutshell, performance optimisation is the process of making slow computer systems faster. This could have different meanings, including making code, software or other changes:
- To allow rapid execution
- Operating with less memory storage or other resources
- Working more efficiently
The focus here is on making the software more responsive and executing more rapidly.
Levels of Optimisation
The performance issue can be on one or many different levels of optimisation. The higher levels tend to come early on in the initial building of the software. for example, if a solution has been built on a NoSQL database and later on it’s discovered that it cannot handle 100 Billion records, and architectural rethink can be challenging.
The issue could sometimes be on lower levels, such as a bug in a plugin/code library that causes slow response times.
Here is an overview of the levels of optimisation:
Design level – on this level design/architectural choices are made. For example, if a system has a strong dependency on network calls, it is best to optimise the solution to as few as possible calls over the network, yet still getting all the required data.
Algorithms and data structures – The way that data is persisted in a database could affect the SQL execution paths as well as sorting and filtering algorithms. It is therefore advisable to plan these structures well before implementation.
Source code level – Some languages do not have automatic garbage collection (disposing of used objects/code). Another example: x ^ 2 can be written as x * x. As systems could grow exponentially, this could potentially cause a great headache.
Debugging and finding the slow issue
identifying ways to improve software performance is as much an art as it is a science. In most cases, a system’s performance normally starts with improving just one or two aspects of the system’s performance. This could be execution time, response time, memory usage, disk space and so forth.
Depending on where the improvements are needed, a different solution could be required. In general, developers tend to spend their time in the source code level.
Here are some examples of encountered cases:
The front end of a web application is exceptionally slow. The user attempts to select a field from a dropdown, yet the dropdown takes 1 minute to load.
- We need to uncover if the issue is in the database layer, an architectural issue or a front end issue
- If the stored procedure is slow, it means that the issue is either in the database structure or stored procedure
- If the stored procedure runs quickly, then the issue is either in code aggregation/arithmetic, network or the plugin
Websites and web applications can have many issues that are out of the software developer’s control. This could include internet issues, browser incompatibility and users not understanding how to use the software.
There are however tools that developers can use to understand user behaviour, performance issues and slow connections (such as the F12 Developer tools), as well as optimizations that can be done. These optimisations include:
- Adding GZip compression for faster file transfers
- Image optimisation by saving for web and devices on photoshop as well as splitting out the main server and the image server.
- Implementing AJAX calls with spin wait animations to make it seem like the page is loading faster
- Caching of data – one can include caching server and browser side so that round trips to the database or server could be reduced.
- Using local storage on the browser for lookups and other information.
Proactive external tools
In many cases, it’s easier to be preventative and using solutions that help in identifying slow parts in a system. For example, Azure performance monitoring allows for capturing a log of information about slow response times and errors that might occur.
It’s also advisable to have a logging database (or logging service), as this might give insights into timeouts and other issues.
There are also many database preformance tools available: some built in, such as RavenDB’s health dashboard and SQLServer’s execution paths that can help a person to bug-track.
The RavenDB Dashboard for performance monitoring
The trade offs for performance optimization
Even though reasonable precautions can be taken to avoid slow code, it’s not always the best solution to start optimising code prematurely. Optimising code before this is an issue can cause unnecessary delays in delivery and wasting precious time.
Some code best practices could actually slow down code. For example in large systems loosely coupled code paired with external libraries implementing dependency injection could contribute to a slow system.
Careful planning and consideration need to be given when starting out on a project. The architecture, infrastructure and technologies need to be chosen carefully, to align with the goals of the software.
Once an issue with performance surfaces, it needs to be investigated, the root of the issue determined and the issue resolved.
Though this sounds like an easy task, it’s not necessarily something quick.
Simply be effecitve.