Java'da yeniyim ve dün gece bazı kodlar çalıştırıyordum ve bu gerçekten beni rahatsız etti. For X döngüsünde her X çıkışını görüntülemek için basit bir program yapıyordum ve modül olarak variable % variable
vs variable % 5000
ya da değil olarak kullandığımda performansta büyük bir düşüş fark ettim . Birisi bana bunun neden olduğunu ve buna neden olduğunu açıklayabilir mi? Böylece daha iyi olabilirim ...
İşte "verimli" kodu (sözdizimi biraz yanlış alırsanız üzgünüm şu anda kod ile bilgisayarda değilim)
long startNum = 0;
long stopNum = 1000000000L;
for (long i = startNum; i <= stopNum; i++){
if (i % 50000 == 0) {
System.out.println(i);
}
}
İşte "verimsiz kod"
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 50000;
for (long i = startNum; i <= stopNum; i++){
if (i % progressCheck == 0) {
System.out.println(i);
}
}
Farkları ölçmek için bir tarih değişkenim olduğunu ve bir kez yeterince uzun olduğunda, birincisi 50ms, diğeri 12 saniye sürdü. Bilgisayarınız benimkinden daha verimli ise veya ne değilse , artırmanız stopNum
veya azaltmanız gerekebilir progressCheck
.
Bu soruyu internette aradım, ancak bir cevap bulamıyorum, belki de doğru sormuyorum.
EDIT: Sorumun çok popüler olmasını beklemiyordum, tüm cevapları takdir ediyorum. Alınan zamanın her yarısında bir kıyaslama yaptım ve verimsiz kod oldukça uzun sürdü, saniyenin 1 / 4'ü vs 10 saniyede veriliyor veya alıyor. Println kullanıyorlar, ancak her ikisi de aynı miktarda yapıyorlar, bu yüzden özellikle tutarsızlık tekrarlanabilir olduğundan, bunu çok fazla çarpıtacağını hayal etmem. Cevaplara gelince, Java'da yeni olduğum için, hangi cevabın en iyi olduğuna karar vermesine izin vereceğim. Çarşamba günü bir tane seçmeye çalışacağım.
EDIT2: Ben bu gece başka bir test yapacağım, burada modül yerine, sadece bir değişkeni arttırır ve progressCheck'e ulaştığında, bir tane gerçekleştirir ve sonra bu değişkeni 3. seçenek için 0'a sıfırlar.
EDIT3.5:
Bu kodu kullandım ve aşağıda sonuçlarımı göstereceğim .. Harika yardım için TÜM teşekkürler! Ben de uzun 0'ın kısa değerini karşılaştırmayı denedim, bu yüzden tüm yeni kontrollerimi tekrar tekrar "65536" kez gerçekleşir.
public class Main {
public static void main(String[] args) {
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 65536;
final long finalProgressCheck = 50000;
long date;
// using a fixed value
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if (i % 65536 == 0) {
System.out.println(i);
}
}
long final1 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
//using a variable
for (long i = startNum; i <= stopNum; i++) {
if (i % progressCheck == 0) {
System.out.println(i);
}
}
long final2 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using a final declared variable
for (long i = startNum; i <= stopNum; i++) {
if (i % finalProgressCheck == 0) {
System.out.println(i);
}
}
long final3 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using increments to determine progressCheck
int increment = 0;
for (long i = startNum; i <= stopNum; i++) {
if (increment == 65536) {
System.out.println(i);
increment = 0;
}
increment++;
}
//using a short conversion
long final4 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if ((short)i == 0) {
System.out.println(i);
}
}
long final5 = System.currentTimeMillis() - date;
System.out.println(
"\nfixed = " + final1 + " ms " + "\nvariable = " + final2 + " ms " + "\nfinal variable = " + final3 + " ms " + "\nincrement = " + final4 + " ms" + "\nShort Conversion = " + final5 + " ms");
}
}
Sonuçlar:
- sabit = 874 ms (normalde 1000 ms civarında, ancak 2 gücü olması nedeniyle daha hızlı)
- değişken = 8590 ms
- son değişken = 1944 ms (50000 kullanılırken ~ 1000 ms)
- artış = 1904 ms
- Kısa Dönüşüm = 679 ms
Şaşırtıcı olmayan bir şekilde, bölünme eksikliği nedeniyle, Kısa Dönüşüm "hızlı" yoldan% 23 daha hızlıydı. Bu not etmek ilginç. Bir şeyi her 256 kez (veya orada) göstermeniz veya karşılaştırmanız gerekiyorsa, bunu yapabilir ve
if ((byte)integer == 0) {'Perform progress check code here'}
65536 (güzel bir sayı değil) ile "Nihai bildirilen Değişken" modülünde modül kullanılarak bir son FAALİYET NOTU sabit değerin yarısı kadar yavaştı (daha yavaş). Daha önce aynı hızda kıyaslama yapıyordu.
final
önündeprogressCheck
değişkeni, hem yine aynı hızda çalışır. Bu, derleyicinin veya JIT'inprogressCheck
sabit olduğunu bildiğinde döngüyü optimize etmeyi başardığına inanmamı sağlıyor .