Chris
Chris

Reputation: 2060

Java - Efficient way to access an array

it's been some time since I last coded in Java, but I need a little hint here. We have a simple function - note that this is C:

void update(double *source, double *target, int n) {
      for(int i = 0; i < n; ++i)
            target[i] = source[i] * i; // well, actually a bit more complicated, just some kind of calculation
}

So, now I need to recode this function in Java - efficiently. My problems are:

Note that source and target are large arrays, storing up to 1 million elements

Upvotes: 1

Views: 922

Answers (6)

soulcheck
soulcheck

Reputation: 36767

Java uses call-by-object semantic, so there is no copying.

Upvotes: 1

Mike Bailey
Mike Bailey

Reputation: 12817

In Java it's almost the same thing:

static void update(double[] source, double[] target, int n)
{
    for (int i = 0; i < n; i++)
        target[i] = source[i] * i;
}

You don't copy any memory. When you pass an array into this function, it's passing a reference to an array by value.

In general, Java passes function arguments by value. But in the case of arrays and user defined classes, the objects you're dealing with are always reference types. So function calls on classes and arrays are always passing the class/array reference by value.

So if you have a class that looks like:

class Foo
{
  int[] A; // For arguments say let's say this contains 1 million items always
}

and you have a function that you can call on it:

static void Bar(Foo f)
{
    ....
}

It only passes the reference to the Foo, it doesn't make a copy of the data at all.

Upvotes: 6

Ed Staub
Ed Staub

Reputation: 15690

Java uses references for arrays (and other objects). The value of the reference, not the array itself, is passed in method calls, with cost similar to C pointers. If you don't need to expand them dynamically, simple arrays are the fastest data structure to use.

Otherwise, consider ArrayList<Double>. But these are much more expensive, in both speed and size, because each double is "boxed" in a Double object.

A third alternative is to use a relevant resizable list class from a library with high-performance primitive collections, like Trove's TDoubleArrayList.

A question you didn't ask, is whether Java will use any relevant SIMD features of your processor for a simple loop like this. And I'm glad you didn't, because I don't know. But I'm fairly confident that if it is smart enough to use them, it will only be for simple arrays.

Upvotes: 1

darnir
darnir

Reputation: 5180

The Java Spec says that everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java. But, don't be fooled by this, the internal working is pretty complex, and you can actually manipulate the arrays the way you want.

Verbatim from Oracle's java Tutorials:

Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level.

Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail.

the code to use is similar and straightforward:

void update(double source[], double target[], int n)
{
    for (int i = 0; i < n; i++)
        target[i] = source[i] * i;
}

For a better understanding of what I mentioned, have a look at this question: Is Java "pass-by-reference" or "pass-by-value"?

As to your question of data structures, use an Array. Looking at your snippet, it is clear that you need random access, so just stick to good ol' arrays..

Upvotes: 1

Sachin
Sachin

Reputation: 18747

Arrays are passed by reference, (the value of the reference is passed). So there won't be any new copy of array.

Code will be quite similar:

void update(double source[], double target[], int n)
{
    for (int i = 0; i < n; i++)
        target[i] = source[i] * i;
}

What do you mean by 'data structure for array'? Array itself is a data structure. You anyways have to access each element for the type of operation you are trying to do. So array itself is a good data structure I guess. You may wanna look at ArrayList.

Upvotes: 2

Kashyap
Kashyap

Reputation: 17451

As some others have already pointed out by-ref / by-value is a C/C++ thing and not applicable to Java.

Now unless you're doing some real native coding passing these arrays C/C++ to / fro Java:

Given that in C code array is passed as pointer (void update(double *source, double *target, int n)) I assume it's size is dynamic, if so your signature in Java should be void update(List<Double> source, List<Double> target, int n). Let the caller decide if it's an ArrayList or Vector or LinkedList or ...

But if you're into some JNI (passing these arrays C/C++ to / fro Java) then perhaps we need to consider other aspects.

Upvotes: 1

Related Questions