Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Optimization Tips for C# Code
C# code optimization involves writing efficient code that executes faster and uses memory more effectively. Here are essential optimization tips that can significantly improve your application's performance.
Prefer Generic Collections Over Non-Generic
Use List<T> instead of ArrayList whenever possible. Generic collections provide type safety and better performance by avoiding boxing and unboxing operations −
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
class Program {
public static void Main() {
// Inefficient - ArrayList with boxing
ArrayList arrayList = new ArrayList();
Stopwatch sw1 = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++) {
arrayList.Add(i); // Boxing occurs here
}
sw1.Stop();
// Efficient - Generic List
List<int> list = new List<int>();
Stopwatch sw2 = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++) {
list.Add(i); // No boxing
}
sw2.Stop();
Console.WriteLine("ArrayList time: " + sw1.ElapsedMilliseconds + " ms");
Console.WriteLine("List<int> time: " + sw2.ElapsedMilliseconds + " ms");
}
}
The output demonstrates the performance difference −
ArrayList time: 45 ms List<int> time: 12 ms
Use Bit Shifting for Fast Division and Multiplication
For powers of 2, bit shifting operations are significantly faster than division and multiplication operators −
using System;
using System.Diagnostics;
class Program {
public static void Main() {
int number = 1000;
int iterations = 10000000;
// Slow division
Stopwatch sw1 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++) {
int result = number / 4;
}
sw1.Stop();
// Fast bit shifting (equivalent to division by 4)
Stopwatch sw2 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++) {
int result = number >> 2;
}
sw2.Stop();
Console.WriteLine("Division time: " + sw1.ElapsedMilliseconds + " ms");
Console.WriteLine("Bit shift time: " + sw2.ElapsedMilliseconds + " ms");
Console.WriteLine("1000 / 4 = " + (1000 / 4));
Console.WriteLine("1000 >> 2 = " + (1000 >> 2));
}
}
The output shows the performance improvement −
Division time: 28 ms Bit shift time: 8 ms 1000 / 4 = 250 1000 >> 2 = 250
Use Short-Circuit Evaluation
Logical operators like && and || provide short-circuit evaluation, stopping evaluation once the result is determined. This reduces unnecessary computations −
using System;
class Program {
public static void Main() {
int x = 5;
int y = 0;
// Short-circuit AND - second condition not evaluated if first is false
if (x > 10 && ExpensiveOperation()) {
Console.WriteLine("Both conditions true");
} else {
Console.WriteLine("First condition false - ExpensiveOperation not called");
}
// Short-circuit OR - second condition not evaluated if first is true
if (x > 0 || AnotherExpensiveOperation()) {
Console.WriteLine("First condition true - AnotherExpensiveOperation not called");
}
}
static bool ExpensiveOperation() {
Console.WriteLine("ExpensiveOperation called");
return true;
}
static bool AnotherExpensiveOperation() {
Console.WriteLine("AnotherExpensiveOperation called");
return false;
}
}
The output demonstrates short-circuit evaluation −
First condition false - ExpensiveOperation not called First condition true - AnotherExpensiveOperation not called
Optimize String Operations
Use StringBuilder for multiple string concatenations instead of the + operator, which creates new string objects each time −
using System;
using System.Text;
using System.Diagnostics;
class Program {
public static void Main() {
int iterations = 10000;
// Inefficient string concatenation
Stopwatch sw1 = Stopwatch.StartNew();
string result1 = "";
for (int i = 0; i < iterations; i++) {
result1 += "Hello ";
}
sw1.Stop();
// Efficient StringBuilder
Stopwatch sw2 = Stopwatch.StartNew();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < iterations; i++) {
sb.Append("Hello ");
}
string result2 = sb.ToString();
sw2.Stop();
Console.WriteLine("String concatenation time: " + sw1.ElapsedMilliseconds + " ms");
Console.WriteLine("StringBuilder time: " + sw2.ElapsedMilliseconds + " ms");
Console.WriteLine("Performance improvement: " +
Math.Round((double)sw1.ElapsedMilliseconds / sw2.ElapsedMilliseconds, 2) + "x");
}
}
The output shows dramatic performance improvement −
String concatenation time: 156 ms StringBuilder time: 2 ms Performance improvement: 78x
Optimization Comparison
| Technique | Inefficient Approach | Optimized Approach | Performance Gain |
|---|---|---|---|
| Collections | ArrayList | List<T> | 3-4x faster |
| Division by power of 2 | number / 4 | number >> 2 | 3-4x faster |
| String concatenation | string + operator | StringBuilder | 50-100x faster |
| Conditional evaluation | & and | operators | && and || operators | Variable improvement |
Conclusion
Effective C# optimization focuses on using appropriate data structures, leveraging bit operations for mathematical calculations, and utilizing short-circuit evaluation. These techniques can provide significant performance improvements, especially in performance-critical applications and loops with high iteration counts.
