l will introduce tips for optimizing the performance of your .NET applications, complete with illustrative examples in C#.
- Check with NULL value
Not good: The==
operator can be overridden. So, no guarantee that the results will be as we expectvar lstEmployee = GetEmployees();
if (lstEmployee == null)
{
// ...
}
Good: Using
is
operator insteadvar lstEmployee = GetEmployees();
if (lstEmployee is null)
{
// ...
}
- Using
IDisposable
interface to release unmanaged resources
Not good: unmanaged resources might not be released, causing potential memory leakspublic class Stock
{
private Stream _ioStream;
public Stock(string filePath)
{
_ioStream = File.OpenRead(filePath);
}
}
Good: Release resource after usingpublic class Stock: IDisposable
{
private Stream _ioStream;
public Stock(string filePath)
{
_ioStream = File.OpenRead(filePath);
}
// Disposing the unmanaged resource.
public void Dispose()
{
_ioStream?.Dispose();
}
}
- Using
ConfigureAwait(false)
to prevent deadlocks
Not good: a risk of potential deadlocks may be occurredpublic async Task<string> LoadData()
{
var data = await ReadData();
return ProcessData(data);
}
Good: Using ConfigureAwait(false) to avoid potential deadlockspublic async Task<string> LoadData()
{
// Use ConfigureAwait(false) to avoid potential deadlocks
var data = await ReadData().ConfigureAwait(false);
return ProcessData(data);
}
- Using
Parallel
loops to take advantage of multicore CPUs
Not good: a standard for loop is used to process the data collection, it will execute of sequential operations
private void ProcessData(List<int> data)
{
for (int i = 0; i < data.Count; i++)
{
TakeOperation(data[i]);
}
}
Good: Using Parallel loops can speed up processing of large collections, helping to optimize processing times
private void ProcessData(List<int> data)
{
Parallel.ForEach(data, item => TakeOperation(item));
}
- Force immediate execution using
ToList()
orToArray()
when needed to improve performance
Not good: IEnumerable will be enumerated multiple times when processing.public IEnumerable<int> GetOddNumbers(IEnumerable<int> numbers)
{
var odds = numbers.Where(n => n % 2 != 0);
return odds;
}
Good:
public IReadOnlyList<int> GetOddNumbers(IEnumerable<int> numbers)
{
var odds = numbers.Where(n => n % 2 != 0);
return odds;
}
- Using StringBuilder instead of concatenate strings in loops
Not good: a new string object is created when each element of "stringArray" is appended to "result", wasting processing time and memory
private string ProcessString(string[] stringArray)
{
string result = "";
for (int i = 0; i < stringArray.Count; i++)
{
result += stringArray[i];
}
return result;
}
Good: use only one StringBuilder, save processing time and memory
private string ProcessString(string[] stringArray)
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < stringArray.Count; i++)
{
stringBuilder.Append(stringArray[i]);
}
return stringBuilder.ToString();
}
- Using
Span
over arrays to circumvent unnecessary memory allocations and copying
Not good: Using the arrays may lead to unnecessary memory allocations and copying
byte[] inputData = GetData();
ProcessingData(inputData);
Good: Using Span<T> helps avoid additional memory allocation and copying
byte[] inputData = GetData();
Span<byte> spanData = inputData.AsSpan();
ProcessingData(dataSpan);
- Using
Lazy Loading
for Resources
Not good: Loading image resource when not needed
var employeeImage = LoadImage();
// Some processsing
Good: Loading image resource when need to use
Lazy<Bitmap> employeeImage = new Lazy<Bitmap>(() => LoadImage());
// After doing some processsing
//...
// Load the image when accessed
Bitmap actualEmployeeImage = employeeImage.Value;
Conclusion:These are just a few examples for improving performance when working with C#.
I hope you find this article is helpful.
References:
https://www.c-sharpcorner.com/UploadFile/dacca2/5-tips-to-improve-performance-of-C-Sharp-code/
https://dev.to/bytehide/7-simple-optimization-tips-in-c-nhn
https://code-maze.com/csharp-tips-improve-quality-performance/
https://www.bytehide.com/blog/performance-optimization-tips-csharp
Image source: https://www.freepik.com/free-vector/stream-binary-code-design_16399103.htm