java - Why is printing "B" dramatically slower than printing "#"?

ID : 215

viewed : 283

Tags : javaperformanceloopsfor-loopsystem.outjava





Top 5 Answer for java - Why is printing "B" dramatically slower than printing "#"?

vote vote

100

Pure speculation is that you're using a terminal that attempts to do word-wrapping rather than character-wrapping, and treats B as a word character but # as a non-word character. So when it reaches the end of a line and searches for a place to break the line, it sees a # almost immediately and happily breaks there; whereas with the B, it has to keep searching for longer, and may have more text to wrap (which may be expensive on some terminals, e.g., outputting backspaces, then outputting spaces to overwrite the letters being wrapped).

But that's pure speculation.

vote vote

84

I performed tests on Eclipse vs Netbeans 8.0.2, both with Java version 1.8; I used System.nanoTime() for measurements.

Eclipse:

I got the same time on both cases - around 1.564 seconds.

Netbeans:

  • Using "#": 1.536 seconds
  • Using "B": 44.164 seconds

So, it looks like Netbeans has bad performance on print to console.

After more research I realized that the problem is line-wrapping of the max buffer of Netbeans (it's not restricted to System.out.println command), demonstrated by this code:

for (int i = 0; i < 1000; i++) {     long t1 = System.nanoTime();     System.out.print("BBB......BBB"); \\<-contain 1000 "B"     long t2 = System.nanoTime();     System.out.println(t2-t1);     System.out.println(""); } 

The time results are less then 1 millisecond every iteration except every fifth iteration, when the time result is around 225 millisecond. Something like (in nanoseconds):

BBB...31744 BBB...31744 BBB...31744 BBB...31744 BBB...226365807 BBB...31744 BBB...31744 BBB...31744 BBB...31744 BBB...226365807 . . . 

And so on..

Summary:

  1. Eclipse works perfectly with "B"
  2. Netbeans has a line-wrapping problem that can be solved (because the problem does not occur in eclipse)(without adding space after B ("B ")).
vote vote

80

Yes the culprit is definitely word-wrapping. When I tested your two programs, NetBeans IDE 8.2 gave me the following result.

  1. First Matrix: O and # = 6.03 seconds
  2. Second Matrix: O and B = 50.97 seconds

Looking at your code closely you have used a line break at the end of first loop. But you didn't use any line break in second loop. So you are going to print a word with 1000 characters in the second loop. That causes a word-wrapping problem. If we use a non-word character " " after B, it takes only 5.35 seconds to compile the program. And If we use a line break in the second loop after passing 100 values or 50 values, it takes only 8.56 seconds and 7.05 seconds respectively.

Random r = new Random(); for (int i = 0; i < 1000; i++) {     for (int j = 0; j < 1000; j++) {         if(r.nextInt(4) == 0) {             System.out.print("O");         } else {             System.out.print("B");         }         if(j%100==0){               //Adding a line break in second loop                   System.out.println();         }                         }     System.out.println("");                 } 

Another advice is that to change settings of NetBeans IDE. First of all, go to NetBeans Tools and click Options. After that click Editor and go to Formatting tab. Then select Anywhere in Line Wrap Option. It will take almost 6.24% less time to compile the program.

NetBeans Editor Settings

vote vote

61

I think it's worth mentioning that push can be called with multiple arguments, which will be appended to the array in order. For example:

var arr = ['first'];  arr.push('second', 'third');  console.log(arr);

As a result of this you can use push.apply to append an array to another array like so:

var arr = ['first'];  arr.push('second', 'third');  arr.push.apply(arr, ['forth', 'fifth']);  console.log(arr);

Annotated ES5 has more info on exactly what push and apply do.

2016 update: with spread, you don't need that apply anymore, like:

var arr = ['first'];  arr.push('second', 'third');    arr.push(...['fourth', 'fifth']);  console.log(arr) ;

vote vote

55

You can use the push and apply functions to append two arrays.

var array1 = [11, 32, 75]; var array2 = [99, 67, 34];  Array.prototype.push.apply(array1, array2); console.log(array1);

It will append array2 to array1. Now array1 contains [11, 32, 75, 99, 67, 34]. This code is much simpler than writing for loops to copy each and every items in the array.

Top 3 video Explaining java - Why is printing "B" dramatically slower than printing "#"?







Related QUESTION?