Java - System.out对性能的影响

时间:2013-09-03 05:36:36

标签: java performance performance-testing outputstream

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

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

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

6 个答案:

答案 0 :(得分:10)

我最近测试(阅读和)编写大量(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
  • data-written-to-file-in-java =>的 37sec
  • data-written-to-buffered-writer-stdout> output.txt =>的 36微秒

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

因此,请记住,如果您使用Java创建unix命令行工具,其中输出应被定向或传送到其他地方,请不要直接使用System.out!

答案 1 :(得分:8)

System.out.println()

已同步。

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

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

答案 2 :(得分:7)

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

这可以转化为绩效的一些要点:

- >就像Rocket boy所说的那样,println是同步的,这意味着你会在对象头上产生锁定开销,并可能导致线程瓶颈,这取决于你的设计。

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

- >如果您已经记录了这一点,那意味着I / O需要额外的内核时间,如果您的平台不支持异步I / O,这意味着您的CPU可能会在繁忙的等待时停止运行。

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

有很多方法可以解决这个问题,比如拥有一个非常快的I / O,一个专用的巨大机器,如果您的应用程序设计在该控制台打印时不会多线程,则可以对JVM选项进行偏向锁定。

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

答案 3 :(得分:3)

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

答案 4 :(得分:2)

与大多数慢速操作相比,

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

我建议您将输出写入文件,并tail将此文件的输出写入。这样,输出仍然会很慢,但它不会对您的Web服务造成太大的影响。

答案 5 :(得分: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