2

Default Java multidimensional arrays are of fixed number of dimensions and are complex initialized.

But few attempts of custom implementations cause hunderd times slower operation.

Why?

The code below compares two custom classes Array1 and Array2 with built-in arrays. Both custom implementations require hundred more time than built-it.

I have posted entire code onto github as I was told: https://github.com/lodnikova/Try_MultidimBenchmark3

I tried to avoid boxing, recursion and other potential slowdowns.

Also I included benchmarking of NDArray class of Vectorz library.

Also I did repeating of the same operation for three times.

I found that speed is very unpredictable.

Allocating all arrays...
Done.
Writing array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 2.540285659 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 9.411849662 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 5.808331906 seconds
Writing array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 16.246523827 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 8.317891235 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 23.501270648 seconds
Writing array3 (conventional)
Attempt: 0
Attempt 0 done. 60000000 elements in 5.914992997 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 1.120277519 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 13.563776366 seconds
Writing array3 (NDArray of Vectorz)
Attempt: 0
Attempt 0 done. 60000000 elements in 1.461343338 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.943231111 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 1.384088957 seconds
Reading array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.271591626 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.238402884 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.242798686 seconds
Reading array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.192451361 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.17005682 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.17020843 seconds
Reading array3 (conventional)
Attempt: 0
Attempt 0 done. 60000000 elements in 0.221501481 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.205166342 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.20135264 seconds
Reading array4 (NDArray of Vectorz)
Attempt: 0
Attempt 0 done. 60000000 elements in 1.020388133 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.950194307 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.977558831 seconds
Total application time is 97.40557648 seconds
8
  • 1
    What is your question exactly? Commented Nov 10, 2014 at 0:11
  • 1
    Why not create a flat array and programmatically map elements in and out of it? Commented Nov 10, 2014 at 0:12
  • 1
    @hexafraction this is an idea of Array2 class, please see. Commented Nov 10, 2014 at 0:14
  • 1
    @Bohemian why do my both versions work so slow in writing? Commented Nov 10, 2014 at 0:14
  • 1
    Can you run this whole thing in a loop ten times and only count the measurements from the last iteration? Maybe the JIT compiler will kick in after a while. Commented Nov 10, 2014 at 0:17

2 Answers 2

2

The underlying implementation of a fast multidimensional array should be a single linear array. If you have a 2D array of dimensions X and Y then a read from element [i][j] is converted into a read of position [i*X+j]. This can be generalised to higher dimensions. The cpu cache of chunks of memory mean that if you are iterating over the primitive elements of the array they will have been fetched in a block into the processor cache such that iterating over them avoids the trip to main memory. This is exactly what the Java multiple dimensional array is; it's just a convenience wrapper around a single linear slab of memory it is not arrays of arrays of arrays.

You are not accounting for GC. Running the program I see full GC of 14s. When there is no GC then the Array2 runs as fast as the native array. Run with these flags:

-Xmx16g -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

Running the program with those flags shows a lot of GC see this version:

https://gist.github.com/simbo1905/7a2404b8fe9e8b2488c8

Sign up to request clarification or add additional context in comments.

5 Comments

I hav implemented what you said in Array2. By some reason it works slower.
You have not posted the code so no-one can give you an answer. post it as a gist on GitHub or as a fragment of code on pastebin or another site for sharing code.
you have changed the question so i have changed the answer.
How is it possible to disable GC?
It will be, don't worry, I just need time
0

Your implementation is much slower than instantiating a simple multimensionnal array of double because

1) you use Object => to convert Object to double, the program convert Object to Double to double. You need to unbox and box and cast. It's a huge waste of time.

2) you use recursive methods that are slower than iterative ones (which is not needed here).

Note: I don't know what you would do with theses arrays but I'm pretty sure that there is plenty of solutions to avoid instantiating a huge amount of data that could lead to a java heap space memory... It's a waste of memory.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.