What are the first things that come to mind when you think of C#? If you’re like most people, the following phrases might pop into your head: object-oriented, portable code, and .NET Framework.
But if you’re looking to use C# in performance-critical applications, then the following phrases should enter your mind as well: performance, speed, and memory usage. From Dotnetsafer we have decided to put together some basic tips for this.
If you’re working on building an application whose primary concern is performance, then these 10 tips will help you increase the performance of your C# application to meet or exceed your expectations!
Avoid the Garbage Collector
The C# programming language is built on top of the .NET Framework, which in turn was built on top of garbage collection. This helps keep performance pretty fast, but you can still do better by avoiding variables that require a garbage-collection cycle when they are released (like objects). Avoiding garbage collection helps maintain high levels of performance as well as optimizing memory usage.
Use StackAllocators (C# Recycling Allocator)
If your application is doing a lot of memory allocation, you may be able to get better performance by avoiding the cost of freeing and allocating memory yourself. You can achieve that by moving up and down in your heap until you find an unused block, then mark it for reuse. A stack-based allocator does just that. It allocates memory from a region called a stack on top of which new blocks are placed when freed blocks are found.
Don’t Reuse Object References
This is a very common mistake among beginning C# programmers: instead of cleaning up an object and releasing its memory when it’s no longer needed, they simply keep using it until there’s no more memory available.
This can be especially dangerous in server applications where many programs are sharing a server; one program’s leaked object reference could bring down all other programs using that server. To avoid creating leaked references, explicitly set your objects to null when you’re done with them — or make sure you only create as many references as necessary.
Avoid Memory Mapping (for big files/filesystems)
One pitfall when using C#’s
File.ReadAllLines() methods is that they load all content into memory immediately. This can cause performance bottlenecks if you’re dealing with very large files and/or slow storage subsystems, like hard drives. One way around it is using a memory-mapped file, which creates virtual space in memory that looks just like a file on disk.
Avoid Unnecessary Serialization/Deserialization
The .NET Framework provides object serialization and deserialization capabilities out-of-the-box. The same holds true for several core .NET languages such as C#, F#, and Visual Basic .NET. However, under certain circumstances these functions can cause significant performance issues in your application. This is particularly true when a non-trivial amount of data needs to be serialized or deserialized.
If you are using these features on a regular basis it’s important that you understand how they work so that you can select an appropriate strategy for processing your data.
JIT away unused methods
The Just-In-Time (JIT) compiler is a process that reads CIL and translates it into native code. When building an application, you don’t want JIT to compile all your classes — particularly if they’re used only once or several times at startup. By compiling only what’s needed when it’s needed, you can make your app start much faster!
There are several ways you can make sure your startup is faster and one way is by using reflection: Remove unused methods from these objects using
Measure in Production Mode instead of Debug Mode
In many programming languages, applications are executed in a special debug mode that allows developers to do things like set breakpoints and print debug messages. This is a great way for developers to test their code while they’re developing it — and during development it’s essential. But after you’re done coding, you should switch back into production mode before your app goes live.
Executing your app in production mode eliminates those extra lines of code that are essential only during development.
Another last way that I am going to add in order to better optimize a .NET application, is to use a .NET Obfuscator. This will help you to strongly optimize your application and you will get a protected application, avoiding decompilation and reverse engineering.