2016-02-13 85 views
5

Ben örnek amacıyla basit bir sınıf var:Neden Java derleyici önemsiz bir yöntemi optimize etmiyor?

public class Test { 

    public int test1() { 
     int result = 100; 
     result = 200; 
     return result; 
    } 

    public int test2() { 
     return 200; 
    } 
} 

(javap -c Test.class tarafından kontrol) derleyici tarafından üretilen bayt kodu şudur: Neden derleyici optimize etmemektedir

public int test1(); 
Code: 
    0: bipush  100 
    2: istore_1 
    3: sipush  200 
    6: istore_1 
    7: iload_1 
    8: ireturn 

public int test2(); 
Code: 
    0: sipush  200 
    3: ireturn 

test2 yöntemi için üretilen aynı bytecode için test1 yöntemi? En az 100 değerinin hiç kullanılmadığı sonucuna varmak için en azından result değişkeninin sıfırdan başlatılmasını önlemeyi beklerim.

Bunu Eclipse derleyici ve javac ile gözlemledim.

javac sürümü: 1.8.0_72, Java ile birlikte JDK bir parçası olarak yüklenir:

Java(TM) SE Runtime Environment (build 1.8.0_72-b15) 
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode) 
+6

* Java Dil Özellikleri * bu tür herhangi bir optimizasyon gerektirmez, bu nedenle "derleyici" hakkında sadece bir tane varmış gibi konuşmak anlamlı değildir. Hangi derleyiciyi kullandığınızı belirtmelisiniz. – ruakh

+5

klasik cevap, optimizasyonların JVM'de yapılmasıdır (http://stackoverflow.com/questions/5981460/optimization-by-java-compiler) – wero

+0

@ruakh İyi bir açıklama; derleyici bilgileri eklendi. –

cevap

4

Tipik bir Java sanal makinesi, programınızı çalışma zamanında değil, derleme sırasında optimize eder. Çalışma zamanında, JVM, uygulamanızın gerçek davranışı hakkında ve programınızın üzerine yüklediği gerçek donanım hakkında uygulamanız hakkında çok daha fazla şey bilir.

Bayt kodu, programınızın nasıl davranması gerektiği ile ilgili bir açıklamadır. Çalışma zamanı, herhangi bir optimizasyonu bayt kodunuza uygulamakta serbesttir. Tabii ki, bu tür önemsiz optimizasyonların derleme sırasında bile uygulanabileceğini söyleyebiliriz, fakat genel olarak optimizasyonları birkaç adımda dağıtmamak anlamlıdır. Herhangi bir optimizasyon etkili bir şekilde orijinal program hakkında bilgi kaybına neden oluyor ve bu da diğer optimizasyonları imkansız hale getirebilir. Bu, tüm "en iyi optimizasyonlar" her zaman açık değildir dedi. Buna kolay bir yaklaşım, derleme sırasında tüm optimizasyonları (neredeyse) düşürmek ve bunun yerine çalışma zamanında uygulamaktır.

+0

evet - en azından satır numarası bilgisi kaybolur, yani stacktrace doğru olmaz; ve hata ayıklama daha zor olacaktır. – ZhongYu

4

JVM bir kod önbellek denilen şey yaratmak, bayt kodu optimize eder. C++ 'dan farklı olarak, JVM programınız hakkında birçok veri toplayabilir, örneğin, Döngü için ne kadar sıcak?, Bu kod bloğu optimize etmeye bile değer mi?, vb. Bu yüzden burada optimizasyon yapmak çok faydalıdır ve genellikle daha iyi sonuçlar verir.

ancak bazı farklı platforma için, (eğer javac çağırdığınızda yani), kodunuzu bilgisayarınız için en uygun olabilecek baytkoduna java dan çeviri yaparken optimize edin. Yani burada optimizasyon yapmak hiç mantıklı değil.

Örnek olarak, programınızın AES şifrelemesini kullandığını varsayalım. Modern CPU'lar, şifrelemeyi çok daha hızlı hale getirmek için özel donanıma sahip AES'ye özgü komut setlerine sahiptir.

Eğer o da

  • optimize modern CPU'lar gelen alışkanlık fayda programlamak bu durumda bir yazılım seviyesinde talimatlar, ya da
  • yerini alacak, sonra derleme sırasında optimize çalışırJavac AES yönergelerinizi, yalnızca yeni CPU'larda desteklenen eşdeğer CPU-AES yönergelerine sahiptir, bu da uyumluluğunuzu azaltacaktır. eski CPU'lar üzerinde çalışan JVMs bir yazılım seviyesinde bunları optimize edebilir

byptcode olduğu gibi yerine Javac onları bırakırsa, o zaman JVM yeni işlemcilerini kullanarak çalışan, AES olarak tanımaması ve bu işlemci yeteneği yararlanabiliriz çalışma zamanında (kod önbelleği), hem hem de ve uyumluluğu.