Reputation: 2060
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
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
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
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
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
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