Wprowadzenie
Dzisiaj zajmiemy się technikami, które pomogą Wam pisać bardziej wydajne programy w C#. Optymalizacja to sztuka balansowania między czytelnością kodu a jego wydajnością. Pamiętajcie, że przedwczesna optymalizacja może prowadzić do komplikacji kodu, dlatego zawsze mierzcie wydajność przed i po wprowadzeniu zmian.

1. Używanie właściwych struktur danych
Wybór odpowiedniej struktury danych może znacząco wpłynąć na wydajność programu.
Przykład: Lista vs HashSet
/* Nieoptymalne */
List<int> lista = new List<int> { 1, 2, 3, 4, 5 };
bool zawiera = lista.Contains(3); /* O(n) */
/* Optymalne */
HashSet<int> set = new HashSet<int> { 1, 2, 3, 4, 5 };
bool zawieraOpt = set.Contains(3); /* O(1) */
2. Efektywne zarządzanie pamięcią
Zarządzanie pamięcią jest kluczowe dla wydajności aplikacji .NET.
Używanie 'using' dla obiektów IDisposable
/* Nieoptymalne */
SqlConnection connection = new SqlConnection(connectionString);
try
{
connection.Open();
/* Operacje na bazie danych */
}
finally
{
connection.Close();
}
/* Optymalne */
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
/* Operacje na bazie danych */
} /* Automatyczne zamknięcie połączenia */
Unikanie dużych obiektów na stercie
/* Nieoptymalne - duży obiekt na stercie */
byte[] largeArray = new byte[85000];
/* Optymalne - używanie dużych obiektów na LOH */
byte[] largeArray = GC.AllocateArray<byte>(85000, true);
3. Optymalizacja operacji na kolekcjach
Efektywne operacje na kolekcjach mogą znacząco poprawić wydajność.
Używanie właściwych metod LINQ
List<int> numbers = Enumerable.Range(1, 1000000).ToList();
/* Nieoptymalne */
var firstGreaterThan100 = numbers.Where(n => n > 100).First();
/* Optymalne */
var firstGreaterThan100 = numbers.First(n => n > 100);
Unikanie niepotrzebnych materializacji
/* Nieoptymalne - niepotrzebna materializacja */
var result = numbers.Where(n => n % 2 == 0).ToList().Where(n => n % 3 == 0).ToList();
/* Optymalne - łańcuchowanie bez zbędnej materializacji */
var result = numbers.Where(n => n % 2 == 0 && n % 3 == 0).ToList();
4. Używanie StringBuilder dla operacji na stringach
/* Nieoptymalne */
string result = "";
for (int i = 0; i < 10000; i++)
{
result += i.ToString();
}
/* Optymalne */
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append(i);
}
string result = sb.ToString();
5. Asynchroniczne programowanie
Wykorzystanie async/await do poprawy responsywności aplikacji.
public async Task<string> PobierzDaneAsync()
{
using (HttpClient client = new HttpClient())
{
return await client.GetStringAsync("https://api.example.com/data");
}
}
6. Caching
Przechowywanie często używanych danych w pamięci.
private Dictionary<int, string> _cache = new Dictionary<int, string>();
public string PobierzDane(int id)
{
if (_cache.TryGetValue(id, out string value))
{
return value;
}
string noweDane = PobierzDaneZBazyDanych(id);
_cache[id] = noweDane;
return noweDane;
}
7. LINQ - używaj z rozwagą
LINQ jest wygodne, ale może być mniej wydajne niż tradycyjne pętle.
/* Może być mniej wydajne dla dużych kolekcji */
var wynik = lista.Where(x => x > 10).Select(x => x * 2).ToList();
/* Bardziej wydajne */
List<int> wynikOpt = new List<int>();
foreach (var item in lista)
{
if (item > 10)
{
wynikOpt.Add(item * 2);
}
}
8. Unikanie niepotrzebnego tworzenia obiektów
/* Nieoptymalne */
for (int i = 0; i < 1000; i++)
{
string s = new string('a', 100);
/* Użyj s */
}
/* Optymalne */
string s = new string('a', 100);
for (int i = 0; i < 1000; i++)
{
/* Użyj s */
}
9. Używanie struktów zamiast klas dla małych obiektów
public struct Punkt
{
public int X { get; set; }
public int Y { get; set; }
}
/* Zamiast */
public class PunktKlasa
{
public int X { get; set; }
public int Y { get; set; }
}
10. Profilowanie kodu
Zawsze mierz wydajność przed i po optymalizacji. Użyj narzędzi profilujących, takich jak Visual Studio Profiler.
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
/* Twój kod */
stopwatch.Stop();
Console.WriteLine($"Czas wykonania: {stopwatch.ElapsedMilliseconds} ms");
Podsumowanie
Optymalizacja kodu to ważny aspekt programowania, który może znacząco wpłynąć na wydajność Twoich aplikacji. Pamiętaj jednak, że czytelność kodu jest równie ważna, a przedwczesna optymalizacja może prowadzić do niepotrzebnych komplikacji. Jeśli chcesz pogłębić swoją wiedzę na temat optymalizacji kodu w C# oraz innych zaawansowanych technik programowania, zachęcam do sprawdzenia mojego szkolenia online "Zostań Programistą .NET". W szkoleniu tym szczegółowo omawiamy nie tylko optymalizację, ale także wiele innych kluczowych aspektów programowania, które pomogą Ci stać się skutecznym deweloperem .NET. Dziękuję za uwagę! Jeśli masz pytania lub chcesz podzielić się swoimi doświadczeniami z optymalizacją kodu w C#, zostaw komentarz poniżej. Powodzenia w Twojej przygodzie z programowaniem!