2015-12-24 24 views
11

Zrobiłem trochę badań, ale głównie widzę odpowiedzi w języku C++. Najbliższy, do którego przyszedłem, to this. Widziałam też this page, ale tak naprawdę nic nie wyjaśnia.Java - Czy kod wprowadzający będzie korzystny?

Czy są jakieś zalety, jeśli używam drugiego fragmentu kodu? Czy wystąpią zauważalne różnice w wydajności? A co z pamięcią? Co jeśli zrobi się to powtarzalnie?

W tej chwili mam tę funkcję. Jestem pewien, że zaletą jest to czytelność kodu:

private static Bitmap resize(Bitmap image, int maxWidth) { 
    float widthReducePercentage = ((float) maxWidth/image.getWidth()); 
    int scaledHeight = Math.round(image.getHeight() * widthReducePercentage); 

    return Bitmap.createScaledBitmap(image, maxWidth, scaledHeight, true); 
} 

Teraz mam ten drugi fragment kodu:

private static Bitmap resize(Bitmap image, int maxWidth) { 
    return Bitmap.createScaledBitmap(image, maxWidth, Math.round(image.getHeight() * (float) maxWidth/image.getWidth()), true); 
} 

Prostszy przykład byłoby:

for(;;) { 
    String foo = "hello"; 
    Console.print(foo + "world"); 
} 

versus

for(;;) { 
    Console.print("hello" + "world"); 
} 
+0

Uważam, że kompilator i tak optymalizuje rzeczy, więc przykłady z parą testów mogą działać podobnie. W każdym przypadku wpisanie może ułatwić odczytanie kodu. –

+2

Przykłady, które podajesz, nie będą miały żadnej różnicy w wydajności. Nie przejmuj się nawet "optymalizacjami" takimi jak te, po prostu rób to, co najlepiej czyta. –

+0

@LouisWasserman Roger to – pandalion98

Odpowiedz

9

Po pierwsze: nie oznacza to "wstawiania". Zobacz: What is inlining?

Po drugie: nie, nie będzie żadnych mierzalnych różnic w wydajności. W obu przykładach kodu najprawdopodobniej skompilowany kod będzie identyczny dla obu wersji.

+2

Kod bajtowy Java będzie inny, ponieważ zmienne lokalne nie zostaną wyeliminowane (są dostępne do debugowania). JIT i prawdopodobnie kompilator Dalvik usunąłby je. – chrylis

+0

Po opublikowaniu tej odpowiedzi wykonałem prosty eksperyment podobny do LIProf. A skompilowane pliki były rzeczywiście inne. Poza tym użyłem flagi '-g: none', więc nie powinno być żadnych symboli debugowania. Sądzę więc, że to trochę bardziej skomplikowane, niż myślałem. –

3

Oboje są sam mi. ten pierwszy sprawia, że ​​rzeczy są bardziej wyraźne niż te ostatnie.

Istnieją sytuacje, takie jak poniższy blok, który sprawia, że ​​jednolinijki są przydatne.

public boolean isEmpty() { 
    return getCount() != 0; 
} 

Jeśli chcesz, aby łatwiej było czytać, zwłaszcza jeśli chodzi o równaniach, pójść na variable. One-liners sprawiają, że jest prosty i krótki, ale są dobre na krótkie i proste logiki.

To jest moja osobista opinia.

4

Zdefiniowałem dwie proste klasy Test1 i Test2 i skompilowałem je.

public class Test1{ 
    public String f(){ 
     String s = "Hello"; 
     String t = "There"; 
     return s + t; 
    } 
} 

i

public class Test2{ 
    public String f(){ 
     return "Hello" + "There"; 
    } 
} 

Ku mojemu zaskoczeniu, .class pliki nie są tej samej wielkości.

-rw-r--r-- 1 csckzp staff 426 Dec 23 19:43 Test1.class 
-rw-r--r-- 1 csckzp staff 268 Dec 23 19:43 Test2.class 

Być może nie powinienem się dziwić, ponieważ pewna ilość informacji symbolicznych jest przechowywana razem z kodem. Uruchomiłem pliki .class przez dekompilator online. Test1 przebudowano prawie tak było wpisane w Test2, z drugiej strony, w ten sposób decompiled.

public class Test2 { 
    public String f() { 
     return "HelloThere"; 
    } 
} 

optymalizacja kompilatora jasno pokazuje tutaj. Być może w Javie występuje niewielka kara za niezbyt kompaktowy kod.

+1

Nie jestem zaskoczony; kompilator bajtów wykonuje * bardzo * minimalną optymalizację. Ich równoważność zostanie udowodniona w czasie wykonywania. – Veedrac

+1

Kompilator próbuje wyeliminować operacje, których wynik można określić podczas kompilacji. Właśnie dlatego "Hello" + "There" zamieniło się w "HelloThere". –

1

Podczas gdy zmienne lokalne przetrwają tłumaczenie na kod bajtowy, bardzo mało prawdopodobne jest, aby przetrwały kompilację w czasie.Co więcej, nawet gdyby obecne były zmienne lokalne, nie wpłynęłoby to znacząco na wydajność tej metody, ponieważ przeskalowanie mapy bitowej jest o rząd wielkości droższe niż przechowywanie lub pobieranie zmiennej lokalnej.

Twój drugi przykład dotyczący łączenia ciągów znaków wskazuje na niewielki wyjątek od tej reguły, ponieważ obecność zmiennych lokalnych może zahamować czas kompilacji oceny konkatenacji ciągłych ciągów. Ponownie jednak jest mało prawdopodobne, aby miało to znaczący wpływ na środowisko wykonawcze programu, ponieważ prawdopodobnie często nie łączymy stałych ciągów.

Ogólnie rzecz biorąc, efekt polegający na wprowadzaniu lokalnych zmiennych do wydajności środowiska wykonawczego jest bardzo rzadko wymierny, nie mówiąc już o znaczącym. Dlatego czas poświęcony na optymalizację wydajności programisty jest znacznie lepszy, dzięki czemu kod jest łatwy do odczytania i uzasadniony.

Powiązane problemy