2011-01-20 15 views
7

Pozwala porównać dwa kawałki kodu:Czy inicjalizacja zmiennej lokalnej o wartości zerowej ma wpływ na wydajność?

String str = null; 
//Possibly do something... 
str = "Test"; 
Console.WriteLine(str); 

i

String str; 
//Possibly do something... 
str = "Test"; 
Console.WriteLine(str); 

zawsze myślałem, że te fragmenty kodu są równe. Ale po tym, jak budować te mają kod (tryb wydania z optymalizacją sprawdzone) i porównano metody IL generowane zauważyłem, że istnieją jeszcze dwie instrukcje IL w pierwszej próbce:

1-te przykładowy kod IL:

.maxstack 1
.locals init ([0] łańucha)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldstr "test"
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009 call nieważne [mscorlib] System.Console :: WriteLine (ciąg)
IL_000e: ret

2-te Kod próbki IL:

.maxstack 1
.locals init ([0] string str)
IL_0000: ldstr "test"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: zadzwoń void [mscorlib] System.Console :: WriteLine (string)
IL_000c: ret

Prawdopodobnie ten kod jest zoptymalizowany przez kompilator JIT? Podobnie inicjalizacja lokalnej zmiennej bethod o wartości zerowej wpływa na wydajność (rozumiem, że jest to bardzo prosta operacja, ale w każdym przypadku) i powinniśmy jej unikać? Dzięki wcześniej.

+4

Powszechnie uważa się, że źle sformułowana jest inicjalizacja z wartością, która nigdy nie zostanie użyta, po prostu dlatego, że wprowadza zamieszanie (jest przypisana wartość "null", która nie ma znaczenia dla logiki). Wszelkie powiązane trafienie wydajnościowe jest pomijalne; poprzedni powód jest znacznie ważniejszym powodem, aby tego uniknąć. –

+0

@Dan Bryany: Dzięki za komentarz. Zgadzam się z tobą, że nie powinniśmy używać wartości null do inicjalizacji, ale niektórzy programiści wolą używać go do bezpośredniej inicjalizacji. Mam taki w moim zespole :) –

+4

Generalnie wolę nie zadeklarować zmiennej dopóki nie zostanie zainicjalizowany, ponieważ ogranicza to zakres pojęciowy przy próbie zrozumienia kodu (tj. Lokalnie są tak lokalne, jak to tylko możliwe, gdzie są,). Efektem ubocznym tego podejścia jest to, że gdy metoda rośnie, rozmieszczenie mieszkańców ma tendencję do zaznaczania obszarów kodu, gdzie można wyodrębnić nowe metody. –

Odpowiedz

7

http://www.codinghorror.com/blog/2005/07/for-best-results-dont-initialize-variables.html

Podsumowując z wyrobu, po przeprowadzeniu różnych standardów, inicjowanie obiektu do wartości (jako część definicji klasy konstruktor lub jako część sposobu inicjalizacji) może być od około 10-35% wolniej na .NET 1.1 i 2.0. Nowsze kompilatory mogą optymalizować inicjowanie z dala od definicji. Artykuł kończy się zaleceniem uniknięcia inicjalizacji jako zasady ogólnej.

6

Jest nieco wolniejszy, jak wskazuje link Jon.Stromer.Galley. Ale różnica jest zadziwiająco mała; prawdopodobnie z rzędu nanosekundy. Na tym poziomie obciążenie związane z używaniem języka wysokiego poziomu, takiego jak C#, przynosi jakiekolwiek różnice wydajności. Jeśli wydajność jest tak dużym problemem, równie dobrze możesz kodować w C lub ASM lub coś podobnego.

Wartość pisania wyraźnego kodu (cokolwiek to znaczy dla ciebie) znacznie przewyższy wzrost wydajności o 0.00001ms pod względem kosztów w stosunku do korzyści. Właśnie dlatego istnieje C# i inne wysokopoziomowe języki.

Rozumiem, że jest to prawdopodobnie pytanie akademickie i nie pomijam zrozumienia wewnętrznych elementów CLR. Ale w tym przypadku po prostu wydaje się, że nie należy się skupiać.

Powiązane problemy