Faster exit through standard Java version?

In a competition for an online judge competition, I have to output up to 50,000 lines in less than 1 second via standard output (in addition to reading up to 200,000 pairs of integers for which I used a buffer). My logic seems correct, but I continue to reject my views beyond the 1st second. I split my code logic to just output a constant string, and it still exceeds the time limit.

Is there a faster way to output than using System.out.println(String s) for each line of output?

+6
source share
4 answers

I would use one call to System.out.print (or the smallest that makes sense, which should be detected by benchmarking) as follows:

 String str = "line1\nline2\nline3\n ..."; System.out.print(str); 

Edit:

  StringBuilder sb = new StringBuilder(); for (int i = 0; i < 500000; i++) { sb.append(i).append("\n"); } String str = sb.toString(); long nt = System.nanoTime(); System.out.print(str); nt = System.nanoTime() - nt; System.out.print("\nTime(ms): " + (double)nt / 1000000); 

sb.toString() not a free operation.

The above takes ~ 650 ms on my laptop (500,000 instead of the requested 50,000).

Edit2 : with two other tricks if filling time takes place:

  • build a StringBuilder with enough capacity
  • do not add for each line (the code below adds 200 lines each time, for this it uses temp sb1 ); only possible if each line can have the same content. Enjoy it.

     long nt = System.nanoTime(); StringBuilder sb1 = new StringBuilder(400); for (int i = 0; i < 200; i++) { sb1.append("l").append("\n"); } String strSb1 = sb1.toString(); StringBuilder sb = new StringBuilder(1000000); for (int i = 0; i < 2500; i++) { sb.append(strSb1); } System.out.print(sb.toString()); nt = System.nanoTime() - nt; System.out.print("\nTime(ms): " + (double)nt / 1000000); 

~ 500 ms in my case.

+7
source

As noted above, the solution is to build your String using StringBuilder and then print the string returned from calling StringBuilder toString (). This can and should be verified by you.

+4
source

You are probably not using enough buffering. If you write System.out, it will automatically clear each line, so grouping several lines together before writing can add some buffering. Better use the right buffer.

Using StringBuffer has the inherent cost of growing a buffer.

 long start = System.nanoTime(); StringBuilder sb = new StringBuilder(); for(long i=0;i<50*1000;i++) sb.append("Hello World!\n"); System.out.print(sb); long time = System.nanoTime() - start; System.err.printf("Took %d ms%n", time/1000000); 

prints

 Took 30 ms. 

However, on Linux, if you know that stdout is a file, you can write it directly.

 long start = System.nanoTime(); String processId = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; FileOutputStream out = new FileOutputStream("/proc/" + processId + "/fd/1"); BufferedOutputStream bos = new BufferedOutputStream(out); final byte[] str = "Hello World!\n".getBytes(); for (long i = 0; i < 50 * 1000; i++) { bos.write(str); } bos.close(); long time = System.nanoTime() - start; System.err.printf("Took %d ms%n", time/1000000); 

prints

 Took 9 ms. 

However, you need to be careful how much you optimize the code, as you may violate the implied rules of the standard and not accept it.;)

+3
source

It also depends on the OS. If I were you, I would just write a file that is much faster.

If you can not do this, and you start your application. on an OS with an out put console lock (as opposed to a non put out console non-blocking console), you could use writing your own asynchronous registrar. Log4j has login implementations that do this, for example.

Basically, you will have an executing service to which you send the lines, and let it write to the console. While this thread is writing, your original workflow will continue to work, thereby reducing the loss associated with waiting for a message.

Console output in turn is also used better, because by the time it finishes flushing, new messages are ready.

Thus, you can increase the bandwidth.

0
source

Source: https://habr.com/ru/post/896608/


All Articles