Arrays of primitives in java vs C ++

I wanted to know about the performance differences between arrays in c ++ and java. I know that for arrays of objects in java, objects are not stored permanently in memory, only pointers to those objects are stored contiguous. How about primitive types like ints? As far as I know, the JVM does not guarantee that the array will be stored contiguous. I basically want to know what are the main performance differences of primitive arrays between java and C ++. Does the related check also play a role in slowing down arrays in java down?

+3


source to share


2 answers


As far as I know, the JVM does not guarantee that the array will be stored contiguous.



While I don't see a cast iron guarantee that array elements will be stored contiguous, I believe they will be for every major implementation. And for primitive types, primitive values ​​are stored directly - not references. As far as I know, all major implementations collect arrays as well - so if you have byte[]

for example, it doesn't align every byte on a 4 or 8 byte boundary (thus multiplying the space needed by 4 or 8). But the value boolean[]

does not box individual bits (in the implementations I have used) - it new boolean[n]

takes up the same space as new byte[n]

.

+1


source


There are a few things to be aware of:

  • The array of primitives is stored contiguous in Java, at least in the standard JVM. A multidimensional array doesn't have to be contiguous, though: if you do int[][]

    , then each layer will be contiguous, but there may not be two consecutive layers. This has an overhead because finding the meaning is not a simple scale and adds.
  • The linked check is important to the JVM sandbox, so there is nothing you can do to disable it, and yes, it does have an overhead.
  • An array in Java is of constant size. It cannot be changed later. If you want to resize it, you need to copy everything to a new array.
  • There is no pointer arithmetic, so you cannot pass a pointer anywhere through an array. This is not a problem: you are passing the entire array, plus a value indicating the method to start processing from. But sometimes it makes Java methods look slightly different from their C counterparts.
  • Arrays are always initialized in Java: each element is either 0 or false or null (depending on the type). This is because you would otherwise end up with undefined behavior when you read it before writing to it, and Java does its best to avoid undefined behavior. There is also an overhead here.


All that said, there are two things that make this all less problematic than you might think. First, for your typical case of iterating over all the elements in an array, you don't run into much of a problem. The estimation is very simple and can even be optimized by the JIT compiler, which is very well tuned to optimize hard loops. And for another, by far the most important issue with heavy array processing is asymptotic complexity, which is not affected by any of the above. So, while Java is slower in general, you will still find that bubble sort in C is much, much slower than merge in Java.

Another important thing to note is that many of them will help you and provide secure coding. Of course, you can write garbage in Java, but some kinds of garbage are much easier to write in C: override the end of the array and no one will stop you on your tracks.

+1


source







All Articles