3

To speed up my image processing application, I'm trying to address values in an array starting in the middle, and using indices starting at 0.

For example, when I work with two arrays, I often have a situation like this:

public void work(int[] array1, int[] array2, int offset)
{
    int len = array1.length;
    for (int i = 0; i < len; i++)
        array1[i] += array2[i + offset];
}

so I would like to create a new variable, array3 that directly maps into the middle of array2 (not a copy), so I can do this:

public void work(int[] array1, int[] array2, int offset)
{
    int[] array3 = array2[offset]...;
    int len = array1.length;
    for (int i = 0; i < len; i++)
        array1[i] += array3[i];
}

In effect, I want a Java equivalent to this c statement:

int *array3ptr = array2ptr + offset;

Note: I don't have any experience with JNI or anything, so if it boils down to using this, please provide working examples.

Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50

3 Answers3

1

This is not possible to do by using pure Java arrays and the array[index] notation. In Java arrays can never overlap.

You could however wrap your arrays in IntBuffer. If you use a direct buffer (see allocateDirect) you should get real good performance.

A statement such as

int *array3ptr = array2ptr + offset;

would be written as

IntBuffer array3 = array2.slice().position(offset);

These

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • I read somewhere that it should be possible with JNI using `IntBuffer` or something – Mark Jeronimus May 14 '12 at 08:57
  • @Zom-B I don't think so. An array is an actual object which needs to be created whether by pure Java or by JNI. Even of you could re-use the data area, you would still have to create a new object with length field etc. The only working and elegant way IMO is to change your API so that apart from an array it accepts start and end indices, or use `ByteBuffer` and friends, which can wrap arrays for about the same effect. – Michał Kosmulski May 14 '12 at 09:02
  • A direct buffer will only give you a performance boost if you're shuffling the data somewhere (to disk, to the network), rather than just manipulating it in memory. But sure, if you're processing consists of read from disk, manipulate, write back then a direct buffer can help. – Greg Kopff May 14 '12 at 09:46
  • Too bad. I'm not shoving the data around as a whole, I'm manipulating it at the pel level (=individual colors in a pixel). Looking at the source of DirectByteBuffer, I see that the get method checks for out-of-bounds, calculates an index and gets the value from an Unsafe object. This can only be magnitudes slower than just array[x + variable] – Mark Jeronimus May 18 '12 at 08:52
  • Try it out berfore drawing conclusions. array[x + variable] also performs.array bound checks. – aioobe May 18 '12 at 09:24
  • I'm on a tight schedule, and I've already implemented the array version. It will be a while before I find time to change something that works. Right now, the bottleneck of my application is gui, not image manipulation. – Mark Jeronimus May 18 '12 at 09:59
  • Everybody, look at Zom-B, he has profiled his application to make sure he's putting the optimization effort on the bottleneck. This is the opposite of prematura optimization. What an excellent thing to do :-) – aioobe May 18 '12 at 10:41
0

In java even integer arrays are objects on the heap. Hence the int[] array2 is actually directly refering to the integer array in the memory. no copy is created of the object (i.e array), duplicate is only of the reference to the array.

Surender Thakran
  • 3,958
  • 11
  • 47
  • 81
0

I don't have much experience with them, but I think you could be able to do that by wrapping your arrays (and sub-arrays) into IntBuffer instances.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255