简体   繁体   English

Java - System.out 对性能的影响

[英]Java - System.out effect on performance

I've seen this question and it's somewhat similar.我见过这个问题,它有点相似。 I would like to know if it really is a big factor that would affect the performance of my application.我想知道这是否真的是影响我的应用程序性能的一个重要因素。 Here's my scenario.这是我的场景。

I have this Java webapp that can upload thousands of data from a Spreadsheet which is being read per row from top to bottom.我有这个 Java 网络应用程序,它可以从每行从上到下读取的电子表格上传数千个数据。 I'm using System.out.println() to show on the server's side on what line the application is currently reading.我正在使用System.out.println()在服务器端显示应用程序当前正在读取的行。

- I'm aware of creating a log file. - 我知道创建一个日志文件。 In fact, I'm creating a log file and at the same time, displaying the logs on the server's prompt.事实上,我正在创建一个日志文件,同时在服务器的提示上显示日志。
Is there any other way of printing the current data on the prompt?有没有其他方法可以在提示上打印当前数据?

It can have an impact on your application performance.它可能会对您的应用程序性能产生影响。 The magnitude will vary depending on the kind of hardware you are running on and the load on the host.大小将根据您运行的硬件类型和主机上的负载而有所不同。

Some points on which this can translate to performance wise:这可以转化为性能方面的一些要点:

-> Like Rocket boy stated, println is synchronized, which means you will be incurring in locking overhead on the object header and may cause thread bottlenecks depending on your design. -> 就像 Rocket boy 所说的那样, println 是同步的,这意味着您将在对象头上产生锁定开销,并且可能会导致线程瓶颈,具体取决于您的设计。

-> Printing on the console requires kernel time, kernel time means the cpu will not be running on user mode which basically means your cpu will be busy executing on kernel code instead of your application code. -> 在控制台上打印需要内核时间,内核时间意味着 cpu 不会在用户模式下运行,这基本上意味着您的 cpu 将忙于执行内核代码而不是应用程序代码。

-> If you are already logging this, that means extra kernel time for I/O, and if your platform does not support asynchronous I/O this means your cpu might become stalled on busy waits. -> 如果你已经记录了这个,这意味着额外的内核时间用于 I/O,如果你的平台不支持异步 I/O,这意味着你的 CPU 可能会在忙等待时停止。

You can actually try and benchmark this and verify this yourself.您实际上可以尝试对此进行基准测试并自行验证。

There are ways to getaway with this like for example having a really fast I/O, a huge machine for dedicated use maybe and biased locking on your JVM options if your application design will not be multithreaded on that console printing.有很多方法可以避免这种情况,例如拥有一个非常快的 I/O,一台巨大的专用机器,如果您的应用程序设计不会在该控制台打印上进行多线程,则可能会在您的 JVM 选项上偏向锁定。

Like everything on performance, it all depends on your hardware and priorities.就像所有关于性能的事情一样,这一切都取决于您的硬件和优先级。

I was recently testing with (reading and) writing large (1-1.5gb) text-files, and I found out that:我最近正在测试(读取和)写入大型(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();

is in fact almost 250% faster than其实,几乎250%的速度比

System.out.println(yourString);

My test-program first read about 1gb of data, processed it a bit and outputted it in slightly different format.我的测试程序首先读取大约 1gb 的数据,对其进行一些处理并以稍微不同的格式输出。

Test results (on Macbook Pro, with SSD reading&writing using same disk):测试结果(在Macbook Pro上,SSD读写同盘):

  • data-output-to-system-out > output.txt => 1min32sec数据输出到系统输出 > output.txt => 1min32sec
  • data-written-to-file-in-java => 37sec数据写入文件在 java => 37 秒
  • data-written-to-buffered-writer-stdout > output.txt => 36sec数据写入到缓冲写入器标准输出 > output.txt => 36 秒

I did try with multiple buffer sized between 256-10k but that didn't seem to matter.我确实尝试了多个大小在 256-10k 之间的缓冲区,但这似乎无关紧要。

So keep in mind if you're creating unix command-line tools with Java where output is meant to be directed or piped to somewhere else, don't use System.out directly!因此请记住,如果您使用 Java 创建 unix 命令行工具,其中输出旨在定向或通过管道传输到其他地方,请不要直接使用 System.out!

System.out.println()

is synchronized.是同步的。

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

If multiple threads write to it, its performance will suffer.如果多个线程写入它,它的性能会受到影响。

Yes, it will have a HUGE impact on performance.是的,它将对性能产生巨大影响。 If you want a quantifiable number, well then there's plenty of software and/or ways of measuring your own code's performance.如果您想要一个可量化的数字,那么有很多软件和/或方法可以衡量您自己的代码性能。

System.out.println is very slow compared to most slow operations.与大多数慢速操作相比,System.out.println 非常慢。 This is because it places more work on the machine than other IO operations (and it is single threaded)这是因为它比其他 IO 操作在机器上放置更多的工作(并且它是单线程的)

I suggest you write the output to a file and tail the output of this file.我建议您将输出写入一个文件并tail该文件的输出。 This way, the output will still be slow, but it won't slow down your web service so much.这样,输出仍然会很慢,但不会降低您的 Web 服务的速度。

Here's a very simple program to check performance of System.out.println and compare it with multiplication operation (You can use other operations or function specific to your requirements).这是一个非常简单的程序来检查 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");
    
 }
}

Output depends on your machine and it's current state.输出取决于您的机器及其当前状态。

Here's what I got on : https://www.onlinegdb.com/online_java_compiler这是我得到的: 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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM