“Never and ever make a code optimization by heart”
Word “optimization” comes from the Latin word “optimum” or “optimus” which literally means “the best”. This detail is more than an etymological fun. That is, this etymological fact gives us a message; optimization means “the best”, not “the cheapest”, “the biggest”, “the fastest”, “the most”, “the least” etc.
Optimization is one of the main practices of engineering disciplines and it has to consider numerous different viewpoints in order to decide the ways going to the best. However, before creating the best, we have to make our mind up what is the best.
This article tells about performance optimization in C#. NET, specifically ASP.NET MVC under Visual Studio; nevertheless, it is not an ultimate guide. Before getting into the specific points, I want to talk about general rules, advices or maybe some anti-patterns we should consider when deciding before making an optimization. Even though they are not the all tips and techniques, we just tried to create an impression on reader’s mind.
There is no magic stick increasing the code performance. Every method, every practice or every procedure is applied only when they were needed. That is, the most precious quality of a developer or an architect is deciding under which circumstances a piece of code needs optimization. In order to make the best decision, you should take some rules into account.
First of all, do not complicate your code without a noticeable reason. As we told before, optimization is not about the fastest loading code or sending fewer requests. You have to consider the whole process related to your project, like the time and money you spent. In other words, do not get into trivial things and don’t endanger your code for minor benefits. A code optimization must have a reasonable gain. Depending on my coding experience, I can clearly state that a complex code piece is likely to have more bugs than a simple one. Furthermore, in many cases, a readable code is more optimized than a complex code due to maintainability issues.
Secondly, never and ever lose your 10.000 feet perspective. That is, before making a code optimization, make sure that you have taken all aspects into account. By all aspects, I mean time you are given, budget of the project, the main aim of the project, potential future changes etc.
One crucial point is that you should always make a performance monitoring before optimization. In other words, never and ever make a code optimization by heart; be realistic forever. There are tools for monitoring different languages, database systems etc.
Let’s get back to the point. Specific details about performance optimization I want to talk about are as follows;
Caching is one of the most important techniques of performance optimization. Actually, caching is a very detailed subject to talk about. From CPU to the ISP provider, caching can be done in very different levels and there are tons of different caching algorithms and practices. However, we are interested in a pragmatic meaning of caching for a web developer which is basically caching HTML or a specific data in the database to decrease the number of operations conducted in the backend.
Libraries like Memcached for memory level caching and Redis as a NoSQL database are two example tools for caching. Use them, but wisely, since caching has some disadvantages which you should consider. First and the obvious side effect of caching is about data consistency. Secondly, all caching activities require extra codes which checks the item in the cache wheter it exists or not, then writes the cache if necessary. Additionally, a cache refreshing policy has to be determined considering the actual needs. All these make your code more complex, consider about it.
Parallel and Asynchronous Programming
Parallel and Asynchronous programming is another efficient way of performance optimization. In C#.NET (also in some other languages supporting .NET Framework), we have Task object and a legacy Thread object. In fact, Task is a developed and improved object and there is no need for Thread object, I believe. Moreover, in C# we have async and await keywords which lets an improved way of parallel programming.
Always keep in mind that parallel programming is efficient only in specific cases. For example, when you wait an external source. Let’s say, you confirm identity number of a person from a web service provided by the government. Each request takes 2 to 3 seconds. You can reach this service asynchronously and you don’t have to wait to conduct another job.
Always keep in mind that if you use the same resources, parallel programming may not bring about efficiency in total. For instance, in application level, you have done a perfect model of parallel requests and your IIS can respond to a hundred requests in a second. However, if your database is a single instance and only request to just four requests per second, your system can only respond four requests per second. In short, don’t involve in parallel programming because of cool async and await keywords. Focus on bottlenecks and always calculate total benefits instead of the local benefits and consider if is it worth to code complexity.
On the other hand, thread management is not an easy task to handle. I have faced problems caused by zombie threads because of clumsy thread management by colleagues specifically those are new to multithread applications. Secondly, multithread applications are also difficult to debug. Code complexity is another issue by default, not need to talk about it much.
Lazy loading and eager loading are two concepts that are commonly used in ORM frameworks. Don’t use lazy loading if you don’t need specifically, since getting the related data may cost more. On the other hand, don’t be too generous using eager loading; namely, don’t load the whole database for one record. Just make your calculations better and use it wisely.
Be Careful with New Tools and Technologies
Maybe the best optimization practice is being careful about recent learned tools, methods and technologies. Our sector is keen to grow. New methodologies, libraries, frameworks, techniques, database management system etc. occur. The bad side is that, all these frameworks offer perfect tools for performance optimization. However, never and ever trust a third-party tool, a technology or methodology that you are not experienced. Sometimes, misuse of a such tools may cause even data consistency problems.
This aspect is not only for performance optimization, a software developer should go in for this. I have an interesting story, it is not related to optimization but I like it. Once, my colleague who was a team leader in my neighbouring team told me about a junior developer in his team adds interfaces to all classes in the project. When my colleague asked why he is doing this, he replied, “interface is nice”. Most probably, he is not even aware of what the interface is. I assume, he read an article about usage of interfaces and try to apply as much as he can. Or maybe he wants to display his knowledge to his senior, I don’t know. In short, even though there are perfect optimization tools, use only if you know it well; don’t apply it everywhere.
Query Monitoring and SQL Optimization
Maybe the most important performance optimization practice is query optimization. I can assure you that, most of the bottlenecks stems from database. Always keep your database design fair enough. Index necessary tables and columns wisely. And, as a general rule, always monitor before doing it. Namely, don’t create indexes by heart, just watch for bottlenecks. For SQL server, Profiler is a perfect tool. All database management systems have similar tools as well. However, if you have a dedicated database administrator managing your database, forget about all, just make him/her to tell you the most expensive query after his/her indexing work.
Other Points Should be Considered
Always deploy the code built in Release mode, if you have no specific reason. Hence in Debug mode, your code may contain extra assemblies. However, in Release mode, Visual Studio creates the most optimized assembly and no doubt, it is the most efficient version.
Don’t use sessions if you don’t have specific reasons. About a decade ago, session was one of the basic aspects of web programming however they are not so popular today. In our present day worl, because a session consume a piece of memory which is not considered as an efficient method.
Avoid use of recursive methods. When I learned recursive methods, I was a high school student. It used to seem interesting and I had a lot of fun with it. However, it is a well-known fact that recursive methods cause performance problems by nature.
As a C#.NET classic, use StringBuilder class if you have too many string operations. Again, if you haven’t used it yet, just read an article about it and decide whether to use it or not.
To sum up, as I told, this is not an ultimate guide and there are many different techniques and tools used for optimization. However, being aware of the main reason of optimization is much more important than specific tools and techniques. Code optimization is a basic engineering practice and it provides efficient use of resources. However, it is like a fire. Don’t burn the house to get warm.
Suleyman Cabir Ciplak