【问题标题】:Is console text still displayed if no console is present?如果没有控制台,控制台文本是否仍然显示?
【发布时间】:2013-10-05 15:22:00
【问题描述】:

当启动“可运行 jar”时,默认情况下它不会启动控制台。如果您想调用终端,您可以在命令提示符下运行(对于 Windows 用户)“java -jar nameofyourprogram.jar”,您将能够看到控制台。

我的问题是,当您使用 System.out.println() 如果您的控制台未显示并且您将信息打印到控制台时,它是否仍会被打印?它会减慢你的程序吗(对于很多打印语句)

当然,使用 GUI 时,除非您运行我在上面放置的命令,否则您不会加载控制台,所以如果您有很多打印语句,它是否仍然会影响您的程序的速度,并且它们是否仍然打印? (甚至认为没有显示终端/控制台)

【问题讨论】:

    标签: java stream console


    【解决方案1】:
    does it slow down your program at all (for lots of print statements)
    

    是的 您可以使用System.nanoTime();手动测试

    注意我看到有人使用System.currentTimeMillis() 来检查执行时间,但这不是正确的方法。使用System.nanoTime();检查执行时间。

    System.currentTimeMillis() 是使用GetSystemTimeAsFileTime 方法实现的,它本质上只是读取 Windows 维护的低分辨率时间值。读取这个全局变量自然非常快——根据报告的信息,大约需要 6 个周期。无论定时器中断是如何编程的,这个时间值都会以恒定的速率更新 - 取决于平台,这将是 10 毫秒或 15 毫秒(这个值似乎与默认中断周期相关)。

    System.nanoTime() 使用 QueryPerformanceCounter / QueryPerformanceFrequency API 实现(如果可用,则返回 currentTimeMillis*10^6)。 QueryPerformanceCounter(QPC) 根据其运行的硬件以不同的方式实现。通常,它将使用可编程间隔定时器 (PIT)、ACPI 电源管理定时器 (PMT) 或 CPU 级时间戳计数器 (TSC)。访问 PIT/PMT 需要执行慢速 I/O 端口指令,因此 QPC 的执行时间为微秒级。相比之下,读取 TSC 大约需要 100 个时钟周期(从芯片中读取 TSC 并将其转换为基于工作频率的时间值)。您可以通过检查 QueryPerformanceFrequency 是否返回签名值 3,579,545(即 3.57MHz)来判断您的系统是否使用 ACPI PMT。如果您看到 1.19Mhz 左右的值,那么您的系统使用的是旧的 8245 PIT 芯片。否则,您应该会看到一个近似于您的 CPU 频率的值(以任何可能生效的速度限制或电源管理为模。)

    【讨论】:

    【解决方案2】:

    当然,使用 GUI,除非您运行我上面放置的命令,否则您不会加载控制台,所以如果您有很多打印语句,它是否仍然会影响您的程序的速度,并且它们是否仍然打印?

    任何性能问题的最佳答案都是对其进行测试。这是一个快速示例程序:

    import java.io.*;
    
    class Test {
    
        public static void main(String[] args) throws Exception {
            // Untimed, for the sake of JIT compilation
            for (int i = 0; i < 100000; i++) {
                System.out.println("Foo");
            }
            // Now let's time it.
            long start = System.nanoTime();
            for (int i = 0; i < 100000; i++) {
                System.out.println("Foo");
            }
            long end = System.nanoTime();
            String outputPath = "c:\\users\\jon\\test\\results.txt";
            try (FileWriter writer = new FileWriter(outputPath)) {
                writer.write((end - start) + " nanoseconds");
            }
        }
    }
    

    从控制台运行它,但隐藏它,在我的笔记本电脑上我得到 5604097078 纳秒的结果。

    从 Windows 资源管理器运行它,所以没有输出,我得到 3339245234 纳秒的结果。 (显然我已经运行了几次 - 这些只是典型的结果。)因此,虽然写入实际上没有做任何事情的控制台效率要高得多,但它远非免费。是否是您的应用程序中的问题是另一回事。

    不,据我所知,输出真的没有写在任何地方。如果您使用它进行日志记录,最好使用专用的日志记录包,这将允许您禁用它以获得更有效的无操作日志记录,还允许您记录到特定文件或任何您想要的位置想要。

    【讨论】:

    • 据我所知,您仍在写入标准输出,但是没有人(例如控制台)花时间阅读它。
    • 可以尝试运行程序,并将标准输出重定向到文件,我猜这应该会产生一些 GUI 执行时间。
    • 如果输出没有被推送到标准输出上,我实际上会相当震惊,只是因为你在 GUI 模式下运行,因为这显然是程序中的语义变化,比如如果我重定向标准输出对于我的标准输入,在 GUI 模式下运行,假设这禁用了打印语句,将改变我的程序输入。
    • 我也同意使用一些日志记录包,它允许禁用日志记录,“if(is_logging_enabled)”的检查将被 JIT 删除,因为 JIT 检测到它是总是这样,同时,JIT 可能会开始观察对 is_logging_enabled 的写入,以确保它假设的不变量不会被破坏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2020-09-24
    • 2014-04-03
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多