Sprawdź raz i to wystarczy

2
1893
Podczas tworzenia bardzo prostego kodu reprezentującego trening, automatycznie utworzyłem konstruktor inicjujący listę ćwiczeń, jak na przykładzie poniżej*:

Gdy pisałem ten kod przypomniałem sobie wielokrotnie widziany schemat w oprogramowaniu produkcyjnym. W moim przypadku wyglądałby on tak:

Widzisz różnicę? W metodzie AddExercise za każdym razem dokonywane jest sprawdzenie, które w kodzie IL wygląda następująco (zrzut z programu ILSpy zainstalowanego jako plugin do VS – polecam, ma pomocne informacje dot. składni) :

Widzimy, że kod odpowiedzialny za sprawdzenie, czy zmienna _exercises ma wartość null to co najmniej 8 instrukcji i może wpływać negatywnie na wydajność metody.  O ile w naszym przypadku nie jest to żadna przeszkoda, wydajność plasuje się na jednym z ostatnich miejsc w wymaganiach naszego „klienta”, to mogę sobie wyobrazić, że dodajemy na przykład wartości sczytywane z setek tysięcy liczników energii elektrycznej i sprawdzenie to nagle zaczyna wpływać na działanie programu. A wystarczyłoby przecież zainicjować listę w konstruktorze, prawda? (Oczywiście TYLKO w przypadku,jeżeli lista jest prywatna, bądź ma prywatny setter lub gdy tylko my, jako twórcy, się nią posługujemy i nie zrobimy głupoty w stylu ustawienia listy na null – lepiej wtedy w ogóle zadeklarować ją jako private readonly z publicznym property getterem). Korzystając z okazji dodam jeszcze uwagę, czym różni się inicjacja pól klasy wewnątrz konstruktora i poza nim. Otóż w obydwu przypadkach wygenerowany kod IL jest taki sam:

W obu przypadkach lista jest inicjowana w konstruktorze i różni się jedynie kolejnością inicjacji listy i wołania konstruktora klasy bazowej Object.

 *) Kod wygląda jak wygląda, bo nie umiałem znaleźć prostego modułu formatującego. Postaram się rozwiązać  ten problem do czasu następnego wpisu zawierającego kod.
0 0 votes
Article Rating
Subscribe
Powiadom o
guest
2 komentarzy
najstarszy
najnowszy oceniany
Inline Feedbacks
View all comments
Andrzej Błaszczuk
8 lat temu

Pociągnąłbym jeszcze temat w kierunku, czy i dlaczego inicjowanie kolekcji w konstruktorze jest lepsze od inicjowania przy deklaracji.