“B” baskısı neden “#” baskısından çok daha yavaş?


2746

İki 1000x matrisi ürettim 1000:

İlk Matris: Ove #.
İkinci Matris: Ove B.

Aşağıdaki kodu kullanarak, ilk matrisin tamamlanması 8.52 saniye sürdü:

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("#");
        }
    }

   System.out.println("");
 }

Bu kodla, ikinci matrisin tamamlanması 259.152 saniye sürdü:

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B"); //only line changed
        }
    }

    System.out.println("");
}

Önemli ölçüde farklı çalışma sürelerinin ardındaki neden nedir?


Yorum önerilen olarak, baskı sadece System.out.print("#");alır 7.8871, oysa saniye System.out.print("B");verir still printing....

Normalde onlar için çalıştığını belirten diğerleri gibi, örneğin Ideone.com'u denedim ve her iki kod parçası da aynı hızda çalışıyor.

Test Koşulları:

  • Bu testi Netbeans 7.2'den çıktı ve konsoluna koydum
  • System.nanoTime()Ölçümler için kullandım

62
Rastgele üretecin etkisini ortadan kaldırmak için rand.nextInt (4) == 0 ila i <250 değiştirmeyi deneyin. Rastgele nesli yavaşlatan entropi
bitebilir

3
Her ikisi de makinemde aynı miktarda çalışıyor gibi görünüyor, ~ 4 saniye.
Sotirios Delimanolis

155
B baskısının # baskıdan daha fazla zaman aldığını öneriyorsanız ... neden rastgele değişken
r'e

18
Kabul edilen cevaba dayanarak, çıktıyı bir dosyaya veya / dev / null'a yönlendirilmiş olarak çalıştırmayı denemediniz.
Barmar

24
@fejese, Random () bir şifreleme programı değildir ve bu nedenle entropi havuzunu kullanmaz.
Böl

Yanıtlar:


4070

Saf spekülasyon , karakter kaydırma yerine kelime kaydırma yapmaya çalışan ve Bbir kelime karakteri olarak ama #kelime olmayan bir karakter gibi davranan bir terminal kullanmanızdır . Böylece, bir çizginin sonuna ulaştığında ve çizgiyi kıracak bir yer aradığında, #neredeyse anında ve mutlu bir şekilde mola görür ; oysa B, daha uzun süre aramaya devam etmelidir ve kaydırmak için daha fazla metin içerebilir (bu, bazı terminallerde pahalı olabilir, örneğin, geri alanların çıkışı, daha sonra sarılmakta olan harflerin üzerine yazmak için boşluklar çıkarılması).

Ama bu saf spekülasyon.


559
Bu aslında doğru cevap! Çözdükten sonra bir boşluk eklemek B.
Kuba Spatny

261
Zor öğrenilen deneyimlerden gelen bazı cevaplar vardır. TJ ve ben (arkadaş olduğumuzdan) Apple'ın günlerinde büyüdük] [ve zx80 / ​​81. O zamanlar hiçbir kelime sarması yoktu. Bu yüzden ikimiz de kendi yazılarımızı yazdık - bir kereden fazla. Ve bu dersler size yapışıyor, kertenkele beyninize yakılıyorlar. Ancak bundan sonra kod yazmayı denediyseniz, ortam kelimeniz her şeyi sararsa veya çalışma zamanından önce manuel olarak yaparsanız, kelime kaydırma ile ilgili sorunlara girmek daha zordur.
JockM

315
Mükemmel kesinti. Ancak bu dersten genelleştirmeliyiz ve performansı her zaman elimine edilir, / dev / null (Windows'ta NUL) veya en azından bir dosyaya yönlendirilmiş çıktı ile ölçmeliyiz. Herhangi bir Konsolda görüntülemek genellikle çok pahalı IO'dur ve bu kadar çarpıcı bir şekilde kafa karıştırıcı olmasa bile zamanlamaları her zaman bozar.
Bob Kerns

37
@MLLister: sözcük kaydırma System.out.printlnyapmaz; çıktı çıktı şey kelime kaydırma (ve engelleme, bu yüzden System.out.printlnbeklemek zorunda kaldı) yapıyordu .
TJ Crowder

35
@Chris - aslında, algoritmanın doğru zamanlamalarını alma sorununa onları yazdırmamak çözümdür. Bir Konsola (her türden) her baskı yaptığınızda, performansını test ettiğiniz şeyle ilgili olmayan her türlü harici işlemi çağırırsınız. Bu ölçüm prosedürünüzde bir hata, saf ve basit. Öte yandan, sorunu ölçüm olarak değil de tutarsızlığı anlamak olarak görürseniz, evet, yazdırmamak bir hata ayıklama hilesidir. Sorun şu ki, hangi sorunu çözmeye çalışıyorsunuz?
Bob Kerns

209

Her ikisi de Java sürüm 1.8 ile Eclipse vs Netbeans 8.0.2 üzerinde testler yaptım; System.nanoTime()Ölçümler için kullandım .

Eclipse:

Her iki durumda da aynı zamanı aldım - yaklaşık 1.564 saniye .

NetBeans:

  • "#" Kullanma: 1.536 saniye
  • "B" kullanma: 44.164 saniye

Netbeans konsolda baskıda kötü performansa sahip gibi görünüyor.

Daha fazla araştırmadan sonra, problemin bu kodla gösterilen Netbeans'in maksimum tamponunun ( komutla sınırlı değildir ) satır sarılması olduğunu fark ettim System.out.println:

for (int i = 0; i < 1000; i++) {
    long t1 = System.nanoTime();
    System.out.print("BBB......BBB"); \\<-contain 1000 "B"
    long t2 = System.nanoTime();
    System.out.println(t2-t1);
    System.out.println("");
}

Zaman sonuçları 225 milisaniye civarında olduğunda, zaman sonuçları her beşinci yineleme hariç her yinelemeden 1 milisaniyeden azdır . Şuna benzer (nanosaniye cinsinden):

BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
.
.
.

Ve bunun gibi..

Özet:

  1. Eclipse "B" ile mükemmel çalışır
  2. Netbeans, çözülebilen bir satır kaydırma sorununa sahiptir (çünkü problem tutulmada oluşmaz) (B'den sonra boşluk eklemeden ("B")).

32
araştırma stratejilerinizi ayrıntılı bir şekilde açıklayabilir misiniz ve sonunda nihayetinde satır kaydırmanın suçlu olduğunu öğrenmenize ne sebep oldu? (Dedektiflik becerilerinizi merak ediyorum, yani!)
Silph

12

Evet, suçlu kesinlikle kelime sarıyor. İki programınızı test ettiğimde NetBeans IDE 8.2 bana aşağıdaki sonucu verdi.

  1. İlk Matris: O ve # = 6.03 saniye
  2. İkinci Matris: O ve B = 50.97 saniye

Kodunuza yakından baktığınızda, ilk döngünün sonunda satır sonu kullandınız. Ancak ikinci döngüde hiç satır sonu kullanmadınız. Böylece ikinci döngüde 1000 karakterlik bir kelime yazdıracaksınız. Bu bir sözcük kaydırma sorununa neden olur. B'den sonra "" sözcüğü olmayan bir karakter kullanırsak , programı derlemek sadece 5,35 saniye sürer . 100 değer veya 50 değer geçtikten sonra ikinci döngüde satır sonu kullanırsak, sırasıyla yalnızca 8,56 saniye ve 7,05 saniye sürer .

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B");
        }
        if(j%100==0){               //Adding a line break in second loop      
            System.out.println();
        }                    
    }
    System.out.println("");                
}

Diğer bir tavsiye NetBeans IDE ayarlarını değiştirmektir. Her şeyden önce, NetBeans Araçları'na gidin ve Seçenekler'e tıklayın . Bundan sonra Editör'ü tıklayın ve Biçimlendirme sekmesine gidin. Ardından seçmek Anywhere içinde Hattı Wrap Seçeneği. Programı derlemek neredeyse% 6.24 daha az zaman alacaktır.

NetBeans Editör Ayarları

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.