java programação - Por que a impressão “B” é significativamente mais lenta que a impressão “#”?





livro usar (3)


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 - cerca de 1.564 segundos .

Netbeans:

  • Usando "#": 1.536 segundos
  • Usando "B": 44,116 segundo

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

Depois de mais pesquisas, percebi que o problema é line-wrapping de line-wrapping 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")).

Eu gerou 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, imprimindo apenas System.out.print("#"); leva 7.8871 segundos, enquanto System.out.print("B");still printing...

Como outros que apontaram que funciona normalmente para eles, tentei o Ideone.com, por exemplo, e ambos os códigos executam na mesma velocidade.

Condições de teste:

  • Eu executei este teste do NetBeans 7.2 , com a saída em seu console
  • Eu usei System.nanoTime() para medições



A especulação pura é que você está usando um terminal que tenta fazer word-wrapping vez de word-wrapping de caracteres, e trata B como um caractere de palavra, mas # como um caractere que não é de palavra. Então, quando chega ao final de uma linha e procura um lugar para quebrar a linha, ele vê um # quase imediatamente e felizmente quebra ali; 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 e, em seguida, gerando espaços para sobrescrever as letras envolvidas).

Mas isso é pura especulação.




Não é por causa de um código diferente, mas por causa do cache: a RAM é mais lenta do que a CPU registra e uma memória cache fica dentro da CPU para evitar gravar a RAM toda vez que uma variável está mudando. Mas o cache não é grande como a RAM é, portanto, mapeia apenas uma fração dele.

O primeiro código modifica endereços de memória distantes, alternando-os em cada loop, exigindo, assim, a invalidação contínua do cache.

O segundo código não alterna: apenas flui nos endereços adjacentes duas vezes. Isso faz com que todo o trabalho seja concluído no cache, invalidando-o somente depois que o segundo loop for iniciado.





java performance loops for-loop system.out