java - Perché la stampa "B" è notevolmente più lenta della stampa "#"?




performance loops for-loop system.out (3)

Ho generato due matrici di 1000 x 1000 :

Prima matrice: O e # .
Seconda matrice: O e B

Utilizzando il seguente codice, la prima matrice ha impiegato 8,52 secondi per il completamento:

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("");
 }

Con questo codice, la seconda matrice ha richiesto 259.152 secondi per il completamento:

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("");
}

Qual è la ragione dietro ai tempi di esecuzione drammaticamente diversi?

Come suggerito nei commenti, stampa solo System.out.print("#"); prende 7.8871 secondi, mentre System.out.print("B");still printing...

Come altri che hanno sottolineato che funziona normalmente per loro, ho provato ad esempio Ideone.com , ed entrambi i pezzi di codice vengono eseguiti alla stessa velocità.

Condizioni di prova:

  • Ho eseguito questo test da Netbeans 7.2 , con l'output nella sua console
  • Ho usato System.nanoTime() per le misure

Answers

Ho eseguito test su Eclipse vs Netbeans 8.0.2, entrambi con Java versione 1.8; Ho usato System.nanoTime() per le misure.

Eclisse:

Ho avuto la stessa ora in entrambi i casi - circa 1.564 secondi .

Netbeans:

  • Utilizzando "#": 1.536 secondi
  • Usando "B": 44.164 secondi

Quindi, sembra che Netbeans abbia delle cattive prestazioni su print to console.

Dopo ulteriori ricerche mi sono reso conto che il problema è il line-wrapping del buffer massimo di Netbeans (non è limitato al comando System.out.println ), dimostrato da questo codice:

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("");
}

I risultati del tempo sono meno di 1 millisecondo ad ogni iterazione eccetto ogni quinto iterazione , quando il risultato temporale è di circa 225 millisecondi. Qualcosa come (in nanosecondi):

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

E così via..

Sommario:

  1. Eclipse funziona perfettamente con "B"
  2. Netbeans ha un problema di line-wrapping che può essere risolto (perché il problema non si verifica in eclissi) (senza aggiungere spazio dopo B ("B")).

La pura speculazione è che stai usando un terminale che tenta di eseguire il word-wrapping piuttosto che il character-wrapping e tratta B come un carattere word ma # come un carattere non-word. Quindi quando raggiunge la fine di una linea e cerca un posto in cui interrompere la linea, vede un # quasi immediatamente e felicemente si spezza lì; mentre con la B , deve continuare a cercare più a lungo e può avere più testo da avvolgere (che può essere costoso su alcuni terminali, ad esempio, l'output di backspaces, quindi l'output degli spazi per sovrascrivere le lettere che vengono spostate).

Ma questa è pura speculazione.


A volte, una tale domanda può essere posta in un colloquio.

Ad esempio, quando scrivi:

int a = 2;
long b = 3;
a = a + b;

non esiste un typecasting automatico. In C ++ non ci sarà alcun errore nella compilazione del codice sopra, ma in Java si otterrà qualcosa come l' Incompatible type exception .

Quindi per evitarlo, devi scrivere il tuo codice in questo modo:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting




java performance loops for-loop system.out