Java'da bir döngü içinde veya dışında değişkenler bildirirsem bir fark yaratır mı? [kapalı]


13

Olası Çoğaltma:
Değişkenleri nerede beyan ediyorsunuz? Bir yöntemin üst kısmı veya ihtiyacınız olduğunda?

Java'da bir döngü içinde veya dışında değişkenler bildirirsem bir fark yaratır mı?

Bu

for(int i = 0; i < 1000; i++) {
   int temp = doSomething();
   someMethod(temp);
}

buna eşit mi (bellek kullanımına göre)?

int temp = 0;
for(int i = 0; i < 1000; i++) {
   temp = doSomething();
   someMethod(temp);
}

Ya geçici değişken örneğin bir ArrayList ise?

for(int i = 0; i < 1000; i++) {
   ArrayList<Integer> array = new ArrayList<Integer>();
   fillArray(array);
   // do something with the array
}

EDIT: ile javap -cben aşağıdaki çıktı var

Döngü dışında değişken:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iconst_0      
       3: istore_2      
       4: iload_2       
       5: sipush        1000
       8: if_icmpge     25
      11: invokestatic  #2                  // Method doSomething:()I
      14: istore_1      
      15: iload_1       
      16: invokestatic  #3                  // Method someMethod:(I)V
      19: iinc          2, 1
      22: goto          4
      25: return  

Döngü içinde değişken:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: sipush        1000
       6: if_icmpge     23
       9: invokestatic  #2                  // Method doSomething:()I
      12: istore_2      
      13: iload_2       
      14: invokestatic  #3                  // Method someMethod:(I)V
      17: iinc          1, 1
      20: goto          2
      23: return        

İlgilenenler için bu kod:

public class Test3 {
    public static void main(String[] args) {
        for(int i = 0; i< 1000; i++) {
            someMethod(doSomething());
        }   
    }
    private static int doSomething() {
        return 1;
    }
    private static void someMethod(int temp) {
        temp++;
    }
}

bunu üretir:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: sipush        1000
       6: if_icmpge     21
       9: invokestatic  #2                  // Method doSomething:()I
      12: invokestatic  #3                  // Method someMethod:(I)V
      15: iinc          1, 1
      18: goto          2
      21: return   

Ancak optimizasyon çalışma zamanında gerçekleşir. Optimize edilmiş koda bakmanın bir yolu var mı? (Uzun EDIT için özür dilerim)


1
Sökmeye gerçekten baktığınızdan memnunum ve umarım size bir şeyler öğretmiştir. Java deneyimi olan birisinin optimize edilmiş kodla ilgili son sorunuza cevap vermesini umuyordum, ancak belki de bu kısmı Stackoverflow'a gönderebilirsiniz - çok somut bir soru gibi görünüyor.
Joris Timmermans

Evet, optimize edilmiş kodu almaya çalışacağım. (Soru biraz değişti, düzenlemede optimize edilmiş kodla bir şey sordum)
Puckl

Yinelenen bağlantı koptu. Bu soruyu Orijinal yapmanın zamanı geldi.
Zon

Yanıtlar:


4

Bu soruların çoğunun ortak cevabı "neden denemiyorsunuz ve öğrenmiyorsunuz?" Olmalıdır. Java'da, bayt kodundaki farkın değişkeni bildirmenin iki yolu arasında ne olduğunu görmek için, oluşturulan bayt koduna (araca javap denildiğine inanıyorum) bir göz atabilirsiniz.

Bunu yapmak sizin için daha iyi bir öğrenme deneyimidir, çünkü bir daha optimizasyon sorunuyla karşılaştığınızda derleyicinin beklediğiniz şeyi yaptığını doğrulamak için aynı aracı kullanabilirsiniz - kodunuzu gereksiz yere değiştirmekten kaçınmanıza yardımcı olacaktır optimize edicinin kendi başına iyi yaptığı bir stil veya son performansa gerçekten ihtiyaç duyduğunuzda gerçek tweaks'i bulmak.


3

Kısa cevap: hayır. Bu sitede zaten bir yerlerde benzer sorular vardı. Oluşturulan bayt koduna göre kayda değer bir fark yoktur. Gerektiğinde bildirmek daha az kod satırı üretir

Kabul edilen cevap: /software//a/56590/43451


Döngünün içinde sadece bir kez oluşturulabilecek yeni bir nesne oluşturduğunuzda performans ne olacak?
Bubblewrap

3
Bu durumda belli ki performans ve hafıza cezası var. Ancak
op'un sorusundaki

1
Bağlantı koptu.
Zon

1

Bireysel değişken düzeyinde verimlilikte önemli bir fark yoktur, ancak 1000 döngü ve 1000 değişkenle (ima edilen kötü stilin boşver) bir fonksiyonunuz varsa, sistemik farklılıklar olabilir, çünkü tüm değişkenlerin tüm yaşamları üst üste binmek yerine aynı. Bu, yığın boyutu ve çöp toplayıcısının gerekenden daha uzun süre canlı tutulan değişkenleri temizleme yeteneğini etkileyebilir.

Ayrıca, değişkenlere mümkün olan en küçük kapsamı vermek çok daha iyi bir stil. Kazaları önler.


Bu doğru değil - JVM düzeyinde, yerel değişkenler için sınırlı kapsam diye bir şey yoktur.
Michael Borgwardt

(int i = ..) 1000 kez yazdığımda, işlevden çıktığımda yığın üzerinde 1000 farklı değişken olacağını mı söylüyorsunuz?
ddyer

artima.com/insidejvm/ed2/jvm8.html'ye göre "Örneğin, iki yerel değişkenin Örnek3b'deki i ve j yerel değişkenleri gibi üst üste gelmeyen sınırlı kapsamları varsa, derleyiciler aynı dizi girişini kullanabilir Bu sadece mantıklıdır, derleyiciler yığın çerçevesinin boyutunu bu şekilde optimize etmekte serbesttir.
ddyer

1
İyi bir nokta; ancak derleyici optimizasyonlarından bahsediyorsak, derleyici örtüşen sözcüksel kapsamı olan ancak örtüşen bir şekilde kullanılmayan değişkenler için yerel değişken girişlerini neredeyse kolayca yeniden kullanabilir .
Michael Borgwardt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.