web-dev-qa-db-pt.com

Por que a impressão "B" é significativamente mais lenta que a impressão "#"?

Gerei duas matrizes de 1000 x 1000:

Primeira Matriz: O e #.
Segunda Matriz: O e B.

Usando o código a seguir, a primeira matriz levou 8,52 segundos para ser concluída:

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

Com este código, a segunda matriz levou 259.152 segundos para ser concluída:

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 é a razão por trás dos tempos de execução dramaticamente diferentes?


Como sugerido nos comentários, imprimir apenas System.out.print("#"); leva 7.8871 seconds, enquanto System.out.print("B");still printing....

Como outros que apontaram que funciona normalmente para eles, eu tentei Ideone.com por exemplo, e ambos os pedaços de código executam na mesma velocidade.

Condições de teste:

  • Eu executei este teste de Netbeans 7.2 , com a saída em seu console
  • Eu usei System.nanoTime() para medições
2593
Kuba Spatny

A pura especulação é que você está usando um terminal que tenta fazer quebra de linha em vez de quebra de caracteres e trata B como um caractere do Word, mas # como um caractere diferente do Word. Então, quando chega ao final de uma linha e procura por um lugar para quebrar a linha, ele vê um # quase imediatamente e felizmente quebra lá; enquanto que com o B, ele precisa continuar procurando por mais tempo e pode ter mais texto para quebrar (o que pode ser caro em alguns terminais, por exemplo, retornando espaços em branco, em seguida, gerando espaços para sobrescrever as letras envolvidas).

Mas isso é pura especulação.

3917
T.J. Crowder

Realizei testes no Eclipse vs Netbeans 8.0.2, ambos com o Java versão 1.8; Eu usei System.nanoTime() para medições.

Eclipse:

Eu tenho o mesmo tempo em ambos os casos - em torno de 1.564 segundos .

Netbeans:

  • Usando "#": 1.536 segundos
  • Usando "B": 44.164 segundos

Então, parece que o NetBeans tem um desempenho ruim na impressão para o console.

Depois de mais pesquisas, percebi que o problema é quebra de linha do buffer máximo do Netbeans (não é restrito ao comando System.out.println), demonstrado por este código:

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

Os resultados de tempo são inferiores a 1 milissegundo a cada iteração, exceto a cada cinco iterações , quando o resultado do tempo gira em torno de 225 milissegundos. Algo como (em nanossegundos):

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

E assim por diante..

Resumo:

  1. Eclipse funciona perfeitamente com "B"
  2. O NetBeans tem um problema de quebra de linha que pode ser resolvido (porque o problema não ocorre no Eclipse) (sem adicionar espaço após B ("B")).
183
Roy Shmuli