8

I've noticed that

int i=10000000;
boolean isPrime= false;
      while(!isPrime){
           i++;
           System.out.println(item); //this kills performance
           isPrime = checkIfPrime(i);

     }
}

Printing the current value of a variable kills performance. I want to print it once in a while, but keep the cost of this operation low.

How to compare the cost of printing to screen to computation? Are there any tricks to minimize this cost [Should I print one out of 10 records, or will this cost just as much because of conditional check]?


Why do I need this? Well, I am doing fun stuff with Java (such as "find a counterexample for Euler's conjuncture... 27^5 + 84^5 + 110^5 + 133^5 = 144^5 (Lander & Parkin, 1966),"). I want to write a program that is both correct and fast (this counterexample was discovered in 60s, so I should be able to do it in reasonable time). While debugging I want to have as much info and possible and I want to find the counterexample asap. What is my best way to proceed? Print each case? - Too slow. Let it run overnight? What if I missed some i++?

sixtytrees
  • 1,156
  • 1
  • 10
  • 25
  • Your cost is pushing the data to the terminal (to the UI layer) that slows things down, that is the bottle neck – Tim Jun 26 '16 at 00:57
  • Yes. My question is - what are the tricks to provide some data, but not slow down the things? I want to have some output, but I don't want to dramatically slow down things? What would be the cost of saying "if this is 100th attempt print" vs "print each time"? – sixtytrees Jun 26 '16 at 00:58
  • i have written the calculation example in my answer. if you like my answer, you can accept, else let me know if you need more explanation. – Tejus Prasad Jun 26 '16 at 02:23

7 Answers7

7

How to compare the cost of printing to screen to computation?

It is not possible. The cost (i.e elapsed time) of printing depends on where the "printed" characters go. I can trivially construct an example where the cost tends to infinity.

  $ java YourClass | ( sleep 10000000000 )

After a few lines of output, the pipeline buffers will fill, and the print calls in your application will block.

Are there any tricks to minimize this cost [Should I print one out of 10 records, or will this cost just as much because of conditional check]?

There is nothing that won't introduce another overhead; e.g. the overhead of testing whether or not to print.

The only way to entirely eliminate the print overhead is to not print at all while you are trying to measure performance.


What is my best way to proceed? Print each case? - Too slow. Let it run overnight? What if I missed some i++?

First run the program with the print statements to check that you are getting the right answers.

Then remove the print statements and run again to get your performance measures.

However:

  1. Beware of the various traps in writing Java micro-benchmarks.
  2. Trawling through pages and pages of trace prints is not a good way to check for (possible) faults in your program.
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Assuming I am not making this sort of mistakes. What is the ratio of the cost of "test condition (is divisible by 1000)" vs "print each"? Is there a neat way to print every nth result at a low cost (better than "print if this number is divisible by n")? – sixtytrees Jun 26 '16 at 01:21
  • 1
    1) It is `(C(test) + 0.001 * C(print)) / C(print)`. Obviously, `C(print)` has to be measured for the particular way that the printed characters are being handled. 2) No – Stephen C Jun 26 '16 at 01:26
  • 1
    *"Assuming I am not making this sort of mistakes."* - I was not talking about a mistake. My example was to point out that it is **impossible** to give a meaningful estimate for the cost of printing. – Stephen C Jun 26 '16 at 01:36
  • @sixtytrees Ctrl/s is another example. The cost becomes infinite. What you are asking for is impossible in principle. – user207421 Jun 26 '16 at 02:13
3

Yes printing is expensive. A processor can do millions of operations in the time span it takes to print to the terminal/IDE. If you are using eclipse or terminal it it very much time consuming. If you are using a terminal You need to redirect it to a file using >> or > or write it to a file using nio or io library. Print anything only if its inevitable, else i feel you should never print if performance is an issue.

Tejus Prasad
  • 6,322
  • 7
  • 47
  • 75
2

Following is the fastest that you can do to compute the next prime and print as well all those numbers that you tested in the process (provided the next prime does not cause overflow of int):

int i = 10000000;
boolean isPrime = false;
while (!isPrime) {
    i++;
    // System.out.println(item); //this kills performance
    isPrime = checkIfPrime(i);
}
for (int j = 10000001; j <= i; j++) sysout(j);
displayName
  • 13,888
  • 8
  • 60
  • 75
2

If you need to benchmark your code performance, you cant have print statements. For few iterations you have to print, do your debugging and remove the print statements once u know that your code is working correctly. And then do time measure of your code.
Else if you want to have print statements always in your code, its upto you to decide how much delay you can accept. For example, a Xeon processor can give you 28-35 Gflops/IOPS (operations per second), that means the processor can do 35*10^9 increment operations per second(it can do i++ for 35*10^9 times/sec). and as per this (https://stackoverflow.com/a/20683422/3409405) answer System.out.println() takes around 1 ms. so that means if you do print for every 10^6 i++ your time consumed will be doubled.

Community
  • 1
  • 1
Tejus Prasad
  • 6,322
  • 7
  • 47
  • 75
1

How to compare the cost of printing to screen to computation?

By measuring it: Implement both approaches (print every line, print every x lines) and see which one is faster, and keep tuning x for a reasonable trade off between frequent status updates and throughput.

It is important to note that the cost of printing is strongly affected by what you are printing to. Is the stream buffered or does it flush every number? Does it write to memory, to an SSD, an ordinary harddisk, or some drive attached to a slow usb 1 port? That can change write performance by a factor of 1000, which is why you should be measuring your particular use case.

meriton
  • 68,356
  • 14
  • 108
  • 175
1

One approach to this could be the following:

Perform your task in a thread, which updates a common buffer (string? Instance of an information class?) with stuff you want to output, but don't perform the actual output in this thread. Mind locking that buffer so you can access this information safely from different threads.

Then, let a timer/other thread access this common buffer to print out that information. That way you decouple the calculation from the output. The drawback is that you won't see every output, but while the output is generated, the computation continues.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
1

Short answer is: it really depends. Printing text is costly. Hundred "print i" is much more expensive than building string with a stringbuilder and firing "print" once.