9

对于可以在文本编辑器中完成的小型逻辑程序,我使用经典的System.out.println().

我想你们都知道在大量迭代中使用它是多么令人沮丧。为什么这么慢?背后的原因是什么?

4

9 回答 9

33

这与JVM无关。将文本打印到屏幕上简单地涉及操作系统在绘制字母尤其是滚动方面的大量工作。如果将 System.out 重定向到文件,它会快得多。

于 2009-06-04T11:51:19.867 回答
12

这非常依赖于操作系统。例如,在 Windows 中,写入控制台是一个阻塞操作,而且速度也很慢,因此向控制台写入大量数据会减慢(或阻塞)您的应用程序。在 unix 类型的操作系统中,对控制台的写入是缓冲的,因此您的应用程序可以继续畅通无阻,并且控制台将尽可能地赶上。

于 2009-06-04T11:55:03.277 回答
5

是的,写入控制台会产生大量开销。远远大于写入文件或套接字所需的量。此外,如果有大量线程,它们都在同一个锁上竞争。我建议使用 System.out.println 以外的东西来跟踪。

于 2009-06-04T11:51:40.647 回答
3

这与 Java 和 JVM 无关,而与控制台终端有关。在大多数操作系统中,我知道在控制台输出中写入速度很慢。

于 2009-06-04T11:52:15.963 回答
3

缓冲可以提供很大帮助。试试这个:

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

但请注意:您不会看到输出逐渐出现,而是瞬间出现。这很好,但是如果您将它用于调试,并且程序在终止之前崩溃,在某些情况下,您可能不会在崩溃之前看到打印的文本。这是因为缓冲区在崩溃之前没有被刷新。它被打印出来了,但它仍然在缓冲区中,并没有出现在你可以看到它的控制台上。我记得这发生在我身上,在一个令人费解的调试会话中。最好偶尔显式刷新,以确保您看到它:

System.out.flush();
于 2009-11-20T08:02:05.853 回答
1

有些终端只是比其他终端快。即使在一个操作系统中,这也可能会有所不同。

于 2009-06-04T11:55:37.143 回答
1

这可能看起来并没有直接回答您的问题,但我的建议是永远不要使用 System.out 进行跟踪(如果您指的是一种调试,只是为了查看您的应用程序的进步)

System.out 用于调试的问题有几个:

  • 应用程序结束后,当您关闭控制台时,您将丢失日志

  • 一旦您的应用程序正常运行(或评论它们),您就必须删除这些语句。稍后如果您想重新激活它们,您将不得不再次取消评论/评论......乏味

我建议改为使用 log4j 并“监视”日志文件,或者使用 tail 命令 - Windows 也有 Tail - 或者使用 Eclipse 插件,如LogWatcher

于 2009-06-04T12:52:08.667 回答
1

关于写入终端(至少在 Windows 中),我注意到一件有趣的事情。如果窗口最小化,它实际上运行得更快吗?这绝对与 Michael Borgwardt 关于绘图和滚动的回答密切相关。确实,如果您的日志记录足以注意到减速,那么您最好写入文件。

于 2009-06-12T13:37:13.047 回答
-1

缓慢是由于每次换行或刷新时都会发生大量 Java-Native 转换。如果迭代有很多步骤,那么 System.out.println() 就没有多大帮助。如果迭代步骤本身并不重要,您可以仅在每 10 或 100 步调用 System.out.println()。您还可以将 System.out 包装到 BufferedOutputStream 中。当然,始终可以选择通过 ExecutorService 异步打印。

于 2009-06-12T13:31:09.927 回答