Friday, March 7, 2025

Writing Efficient and Sustainable Code in .NET

DImitrije Pesic

Writing Efficient and Sustainable Code in .NET

In modern software development, writing clean and efficient code isn’t just about making it readable—it’s also about performance, maintainability, and sustainability. Poorly written code can lead to increased CPU usage, memory leaks, and inefficient processing, which in turn contributes to higher energy consumption. This post will highlight good coding practices in .NET by comparing bad and optimized examples to help you write greener and more efficient code.

1. Avoiding Unnecessary Loops

❌ Bad Code: Inefficient Looping

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var squaredNumbers = new List<int>();

foreach (var number in numbers)
{
squaredNumbers.Add(number * number);
}

Why it's bad: This uses an explicit loop when a more concise and optimized approach exists.

✅ Good Code: Using LINQ for Efficiency

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(n => n * n).ToList();

Why it's better: LINQ improves readability and allows internal optimizations that may improve performance.

2. Avoiding Unnecessary Object Creation

❌ Bad Code: Creating Objects in Loops

for (int i = 0; i < 100; i++)
{
var sb = new StringBuilder();
sb.Append("Iteration: ").Append(i);
Console.WriteLine(sb.ToString());
}

Why it's bad: A new StringBuilder instance is created on each iteration, leading to excessive memory allocation.

✅ Good Code: Reusing Objects

var sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
sb.Clear();
sb.Append("Iteration: ").Append(i);
Console.WriteLine(sb.ToString());
}

Why it's better: Reusing the StringBuilder reduces memory allocation and improves performance.

3. Optimizing String Concatenation

❌ Bad Code: Using + for String Concatenation in Loops

string result = "";
for (int i = 0; i < 1000; i++)
{
result += i.ToString() + ",";
}

Why it's bad: String concatenation with + creates a new string in each iteration, leading to high memory usage.

✅ Good Code: Using StringBuilder

var sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.Append(i).Append(",");
}
string result = sb.ToString();

Why it's better: StringBuilder minimizes unnecessary memory allocations and improves efficiency.

4. Avoiding Redundant Computation

❌ Bad Code: Recalculating Values Inside a Loop

for (int i = 0; i < list.Count(); i++)
{
Console.WriteLine(list[i]);
}

Why it's bad: list.Count() is evaluated in each iteration, causing unnecessary computation.

✅ Good Code: Storing the Count in a Variable

int count = list.Count;
for (int i = 0; i < count; i++)
{
Console.WriteLine(list[i]);
}

Why it's better: Storing Count in a variable reduces redundant calculations, improving efficiency.

5. Using async and await for Asynchronous Operations

❌ Bad Code: Blocking Calls with .Result

var data = GetData().Result;
Console.WriteLine(data);

Why it's bad: Blocking operations can cause deadlocks and degrade performance.

✅ Good Code: Using await

var data = await GetDataAsync();
Console.WriteLine(data);

Why it's better: Asynchronous execution prevents blocking and improves responsiveness.

Conclusion

Writing efficient, clean, and sustainable code in .NET is not just about best practices—it also reduces resource usage and enhances application performance. By avoiding unnecessary operations, leveraging built-in optimizations, and writing reusable code, developers can contribute to greener and more scalable applications.

Start optimizing your .NET code today and contribute to a more sustainable future!