11

我见过这个问题,它有点相似。我想知道这是否真的是影响我的应用程序性能的一个重要因素。这是我的场景。

我有这个 Java webapp,它可以从电子表格中上传数千个数据,每行从上到下读取。我System.out.println()用来在服务器端显示应用程序当前正在读取的行。

- 我知道创建一个日志文件。事实上,我正在创建一个日志文件,同时在服务器提示符上显示日志。
有没有其他方法可以在提示符上打印当前数据?

4

6 回答 6

14

我最近正在测试(阅读和)编写大型(1-1.5gb)文本文件,我发现:

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();

实际上几乎快250 %

System.out.println(yourString);

我的测试程序首先读取了大约 1gb 的数据,对其进行了一些处理并以稍微不同的格式输出。

测试结果(Macbook Pro,SSD读写同盘):

  • 数据输出到系统输出 > output.txt => 1min32sec
  • 数据写入 java 中的文件 => 37 秒
  • 数据写入缓冲写入器标准输出 > output.txt => 36 秒

我确实尝试过使用大小在 256-10k 之间的多个缓冲区,但这似乎并不重要。

所以请记住,如果您使用 Java 创建 unix 命令行工具,其中的输出旨在被定向或通过管道传输到其他地方,请不要直接使用 System.out!

于 2015-06-29T14:39:44.737 回答
13

它可能会对您的应用程序性能产生影响。大小将根据您运行的硬件类型和主机上的负载而有所不同。

这可以转化为性能方面的一些要点:

-> 正如 Rocket boy 所说,println 是同步的,这意味着您将在对象头上产生锁定开销,并且可能会根据您的设计导致线程瓶颈。

-> 在控制台上打印需要内核时间,内核时间意味着 cpu 不会在用户模式下运行,这基本上意味着你的 cpu 将忙于在内核代码上而不是你的应用程序代码上执行。

-> 如果你已经记录了这个,这意味着额外的内核时间用于 I/O,如果你的平台不支持异步 I/O,这意味着你的 cpu 可能会在繁忙的等待中停止。

您实际上可以尝试对此进行基准测试并自己验证这一点。

有一些方法可以解决这个问题,例如拥有一个非常快速的 I/O,如果您的应用程序设计不会在该控制台打印上实现多线程,则可能是一台专用的大型机器,以及对您的 JVM 选项的偏向锁定。

就像所有关于性能的事情一样,这一切都取决于您的硬件和优先级。

于 2013-09-03T06:14:30.787 回答
10
System.out.println()

是同步的。

 public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }

如果多个线程写入它,它的性能将受到影响。

于 2013-09-03T05:51:51.433 回答
4

是的,它将对性能产生巨大影响。如果您想要一个可量化的数字,那么有很多软件和/或方法可以测量您自己的代码的性能。

于 2013-09-03T05:39:57.753 回答
3

System.out.println 与大多数慢速操作相比非常慢。这是因为它比其他 IO 操作在机器上放置了更多的工作(并且它是单线程的)

我建议您将输出写入文件和tail该文件的输出。这样,输出仍然会很慢,但不会使您的 Web 服务减慢太多。

于 2013-09-03T06:58:27.540 回答
0

这是一个非常简单的程序来检查 System.out.println 的性能并将其与乘法运算进行比较(您可以使用其他特定于您的要求的运算或函数)。

public class Main{

 public static void main(String []args) throws InterruptedException{
             
    
    long tTime = System.nanoTime();
    long a = 123L;
    long b = 234L;
    
    long c  = a*b;
    long uTime = System.nanoTime();
    
    System.out.println("a * b = "+ c +". Time taken for multiplication =  "+ (uTime - tTime) + " nano Seconds");
    
    long vTime = System.nanoTime();
    System.out.println("Time taken to execute Print statement : "+ (vTime - uTime) + " nano Seconds");
    
 }
}

输出取决于您的机器及其当前状态。

这是我得到的:https ://www.onlinegdb.com/online_java_compiler

a * b = 28782. Time taken for multiplication =  330 nano Seconds                                                                                                                     
Time taken to execute Print statement : 338650 nano Seconds 
于 2021-01-22T06:32:42.047 回答