I have three questions about three nested loops:
for (int x=0; x<400; x++)
{
for (int y=0; y<300; y++)
{
for (int z=0; z<400; z++)
{
// compute and store value
}
}
}
And I need to store all computed values. My standard approach would be to use a 3D-array:
values[x][y][z] = 1; // test value
but this turns out to be slow: it takes 192 ms to complete this loop, where a single int-assignment
int value = 1; // test value
takes only 66 ms.
1) Why is an array so relatively slow?
2) And why does it get even slower when I put this in the inner loop:
values[z][y][x] = 1; // (notice x and z switched)
This takes more than 4 seconds!
3) Most importantly: Can I use a data structure that is as quick as the assignment of a single integer, but can store as much data as the 3D-array?
As others pointed, you are comparing apples to oranges. The triple-array is slow because it needs to dereference (internally at least – yes, “there are no pointers in Java”) three times; but then again, you cannot reference a single integer variable…
Because you have decreased cache coherence. The fastest-changing indices should be the last ones, so that most memory accesses occur next to each other, within the same cache blocks, instead of forcing your processor to wait until the blocks are read from the main RAM.
No. There is no such structure, since the integer variable fits into a machine register (quicker even than the processor’s memory cache), and can always be accessed faster than anything else you care to mention. Processor speeds are much, much faster then main memory speeds. If your ‘working set’ (the data that you need to operate on) does not fit into registers or cache, you will have to pay a penalty to fetch it from RAM (or even worse, disk).
This being said, Java does boundary checks on each array access, and does not seem to be too smart about optimizing the boundary checks away. The following comparison may be of interest:
The output, on my system, is
Therefore, there is some room for improvement… but I really don’t think it is worth your while.