W ostatnim poście obiecałem pokazać na przykładzie, że destruktory rzeczywiście mają negatywny wpływ na wydajność. Mamy prostą klasę:
class MyClass { ~ MyClass() { // Jakis bezensowny kod np: for (int i = 0; i < 100; i++){} } }
Następnie stwórzmy kilkaset obiektów:
Stopwatch stopwatch=new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 100 * 10000; i++) { var newInstance = new MyClass(); } stopwatch.Stop(); long duration = stopwatch.ElapsedMilliseconds;
Przyjrzyjmy się teraz diagramowi przedstawiającemu rozkład obiektów względem generacji (CLR Profiler):
Na moim komputerze duration wyniósł 900. Usuńmy destruktor i dokonajmy analogicznej obserwacji:
Czas deklaracji wyniósł 450. Jakie wnioski? Oczywiście użycie destruktorów spowodowało wypromowanie zwalnianych obiektów do drugiej generacji. Proporcje GEN0 do GEN1 niemal są odwrotne – bez destruktora większość obiektów zawalnianych jest w GEN0. Ponadto sama inicjalizacja (wykonanie pętli) zabrała 2x więcej czasu. Rozwiązaniem jest użycie interfejsu IDisposable.
Piszesz że interfejs IDisposable jest leszy niż destruktor pod względem wydajności i jednocześnie linkujesz do posta w którym opisujesz jego prawidłową implementację, która polega m.in. na napisaniu destruktora, więc trochę Cię nie rozumiem. Sugerujesz żeby implementując IDisposable nie pisać destruktora? Czy może rozwiązanie IDisposable + destruktor jest wydajniejsze niż rozwiązanie z samym tylko destruktorem?
@Marcin:
Dobra uwaga. Proszę jednak zauważyć, że w Dispose wywołujemy GC.SupressFinalize(this)- czyli jeśli użytkownik użyje Dispose wtedy destruktor nie będzie wędrował do freachable queue.
Hej.
Mam małe pytanko odnośnie tego i załączonego wpisu, mianowicie:
IDisposable ratuje nas tylko wtedy gdy rzeczywiście go użyjemy prawda? Jeżeli GC sam wywoła nas destruktor to nastąpi w/w problem i nic na to nie poradzimy. Taki urok destruktorów.
Co to są zasoby zarządzalne a niezarządzalne i dlatego GC ma usuwać tylko te drugie? W C# nie ma chyba żadnej metody typu “free”. Jakoś nie mogę sobie tego wyobrazić.