2009-06-04 17 views

Respuesta

33

Esto no tiene nada que ver con la JVM. Imprimir texto a pantalla simplemente implica mucho trabajo para el sistema operativo al dibujar las letras y especialmente desplazarse. Si redirige System.out a un archivo, será mucho más rápido.

+4

+1 para "dibujar las letras y especialmente desplazarse". Gracias – DragonBorn

+1

Por lo tanto, depende de la velocidad del terminal. Una vez usé una terminal con transparencia y otras cosas llamativas. Se veía bien pero funcionaba muy mal, cambiar a otro terminal resolvió estos problemas. – Philipp

+0

En Linux, se puede tratar de eco bigfile.txt y luego redirigirlo eco bigfile.txt> anotherfile.txt para ver la diferencia. – Renaud

5

Ya, hay una gran cantidad de sobrecarga en escribir en la consola. Mucho más grande que el requerido para escribir en un archivo o un socket. Además, si hay una gran cantidad de hilos, todos contendrán en el mismo bloqueo. Yo recomendaría usar algo diferente que System.out.println para rastrear.

3

Esto no tiene nada que ver con Java y JVM, pero con el terminal de la consola. En la mayoría de los sistemas operativos, sé que la escritura en la salida de la consola es lenta.

12

Esto depende mucho del sistema operativo. Por ejemplo, en Windows, escribir en la consola es una operación de bloqueo, y también es lento, por lo que escribir muchos datos en la consola ralentiza (o bloquea) su aplicación. En sistemas operativos de tipo Unix, la escritura en la consola se almacena en un búfer, por lo que su aplicación puede continuar desbloqueada, y la consola se pondrá al día lo que pueda.

1

Algunos terminales son más rápidos que otros. Esto puede variar incluso dentro de un sistema operativo.

1

Esto podría parecer que no responde directamente a su pregunta, pero mi consejo es que nunca use System.out para rastrear (si quiere decir una especie de depuración, para ver el avance de su aplicación).)

los problemas con System.out para la depuración son varias:

  • una vez que termine la aplicación, cuando se cierra la consola perderás el registro

  • usted tiene que quitar esas declaraciones una vez que su aplicación esté funcionando correctamente (o comentarlos). Más tarde, si desea volver a activar ellos, usted tiene que descomentar/comentario nuevo ... tediosa

recomiendo en lugar de usar log4j y "ver" el archivo de registro, ya sea con un comando de la cola - también hay a Tail for Windows - con un plugin de Eclipse como LogWatcher.

-1

La lentitud se debe a la gran cantidad de transiciones Java-Native que ocurren en cada salto de línea o descarga. Si la iteración tiene muchos pasos, el System.out.println() no es de mucha ayuda. Si los pasos de iteración no son tan importantes por sí solos, puede llamar a System.out.println() cada 10 o 100 pasos solamente. También puede ajustar System.out en un BufferedOutputStream. Y, por supuesto, siempre existe la opción de sincronizar la impresión a través de ExecutorService.

1

Una cosa interesante que he notado sobre escribir en la terminal (al menos en Windows). De hecho, se ejecuta mucho más rápido si la ventana se reduce al mínimo. Esto definitivamente está estrechamente relacionado con la respuesta de Michael Borgwardt sobre dibujo y desplazamiento. En realidad, si está iniciando sesión lo suficiente como para notar la desaceleración, es mejor que esté escribiendo en un archivo.

2

El almacenamiento en búfer puede ayudar enormemente.Prueba esto:

System.setOut(new PrintStream(new BufferedOutputStream(System.out))); 

Pero cuidado: no verá la salida aparecen gradualmente, pero en un instante. Lo cual es genial, pero si lo está utilizando para la depuración y el programa se bloquea antes de que finalice, en algunas circunstancias es posible que no vea el texto impreso justo antes del bloqueo. Esto se debe a que el búfer no se vació antes del bloqueo. Se imprimió, pero todavía está en el búfer, y no llegó a la consola donde se puede ver. Recuerdo que esto me sucedió a mí en una sesión de depuración desconcertante. Lo mejor es enjuagar ocasionalmente de forma explícita para asegurarse de verlo:

System.out.flush(); 
Cuestiones relacionadas