2014-04-22 11 views
9

to:sprawdza boolean szybciej niż ustawienie wartości logicznej w java?

if (var) { 
    var = false; 
} 

Versus to:

var = false; 

Czy istnieje różnica prędkości?

+0

, ale zwiększa się złożoność. – Braj

+0

Oczekuję, że druga wersja będzie szybsza. –

+3

Prędkość jest mikroskopijna i nie ma znaczenia. Jeśli musisz ustawić 'var' na' false', ustaw go. Jeśli chcesz sprawdzić, czy obecnie jest to "prawda", zrób to najpierw. – Mena

Odpowiedz

6

Kilka rzeczy wchodzi w grę, ostateczny wpływ na rzeczywistą wydajność to coś, co trzeba zmierzyć w przypadku użycia. Zakładam, że jest to sposób znalazłeś się zdarzyć naprawdę dużo:

  1. przewidywania rozgałęzień - jeśli var jest prawie zawsze fałszywe, co jest, co kod wskazuje, predyktorem oddział będzie prawie zawsze ma rację. Jeśli pole zmienia się często, stanie się to często niedozwoloną gałęzią i będzie kosztowne.

  2. Czytaj tęsknotę - jeśli var jest w większości czytany (i czytaj DUŻO), to unikanie zmiany bez przyczyny może pomóc oprogramowaniu, nie unieważniając linii pamięci podręcznej, na której siedzi. Jeśli do niego napiszesz, każdy inny rdzeń, który ją czyta (i wszystko na tej samej linii podręcznej), będzie musiał pobrać świeżą kopię z brakiem odczytu. Oznacza to, że powyższa metoda może być wolniejsza w celu zwiększenia czytelności odczytów.

  3. Koszt zapisu a koszt odczytu - jeśli zmienna jest niestabilna, to jest to bariera LoadStore, która jest dość droga. Odczytywanie ulotnej (bariera LoadLoad) jest raczej tanie w porównaniu (trafienie w pamięci podręcznej dla często używanej i prawie niezmienionej wartości). Dzięki temu oddział może być bardzo tani.

To jest optymalizacja ludzi, a przykłady można znaleźć w JDK (IIRC), zakładam, że masz powód, aby go rozważyć.

5

pierwszy kod zawiera porównania, więc kompilator może wygenerować kodu bajtowego Javy, który wygląda tak:

public static void main(java.lang.String[]); 
    Code: 
     0: iconst_1  
     1: istore_1  
     2: iload_1  
     3: ifeq   8 
     6: iconst_0  
     7: istore_1  
     8: return  

Dla drugiego kodu wygenerowany kod bajtowy jest krótsza, ponieważ porównanie brakuje:

public static void main(java.lang.String[]); 
    Code: 
     0: iconst_1  
     1: istore_1  
     2: iconst_0  
     3: istore_1  
     4: return  

Maszyna wirtualna potrzebuje więcej czasu na wykonanie 8 poleceń w pierwszym przykładzie niż 4 polecenia w drugim. Chociaż różnica ta nie powinna być wysoka, drugi kod jest jaśniejszy.

Umieść swój kod w prostej głównej metodzie i skompiluj klasę. Następnie uruchom wiersz polecenia i przejdź do katalogu java/bin. Aby rozmontować połączenie klasowe javap -c path/to/YourClass.class >> path/to/bytecode.txt. bytecode.txt będzie zawierał bajt kodu Java klasy.

+5

Kod Bytecode nie jest dobrym wskaźnikiem wydajności, chyba że planujesz spędzić większość czasu w tłumaczu. –

1

"Różnica prędkości", jeśli występuje, będzie zależeć wyłącznie od JVM. Każdy przyzwoity kompilator powinien być w stanie zoptymalizować test, w którym to momencie oba są identyczne.

Wyjątek: jeśli var zostanie zadeklarowana jako volatile, wersja warunkowa będzie zawsze wolniejsza.

W każdym razie, jeśli wydajność jest krytyczna, najlepszą opcją jest pomiar w oczekiwanych warunkach (maszyna, system, JVM, typowe obciążenie itp.).

+0

Mylisz się. Lotne odczyty są znacznie tańsze niż zapisy. Jest to przetestowana optymalizacja dla lotnych zapisów w terenie. –

+0

@NitsanWakart Być może nie było jasne. Jeśli 'var' zostanie zadeklarowany jako' volatile', wówczas instrukcja OP 'if (var) {var = false; } 'zawsze będzie wolniejsze niż' var = false; 'ponieważ kompilator nie zoptymalizuje odczytu' var'; w ten sposób ponosząc koszty zarówno odczytu *, jak i zapisu *, a nie tylko zapisu. Nie oświadczam o różnicy w wydajności między lotnymi odczytami i zapisami. –

+0

Ta instrukcja "zawsze będzie wolniejsza" nie jest prawdziwa. Jest to poprawne tylko wtedy, gdy var jest prawdziwe, co zakłada, że ​​OP nie dzieli się z nami. Kiedy var jest już fałszywy, zapis warunkowy jest zawsze szybszy IME (ponieważ zmienny zapis nie występuje, i jest znacznie droższy niż odczyt). –

Powiązane problemy