1

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:

  • Java has of course no pointers, so how can I pass the arrays efficiently without having large amounts of memory copy operations due to call by value
  • Which data structure is the best to store the arrays

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

Mike Bailey
  • 12,479
  • 14
  • 66
  • 123
Chris
  • 2,030
  • 1
  • 16
  • 22

6 Answers6

6

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.

Mike Bailey
  • 12,479
  • 14
  • 66
  • 123
2

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.

Bhushan
  • 18,329
  • 31
  • 104
  • 137
1

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.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
  • With the caveat that you'd need to construct it with the large size as an argument, and if you *do* expand it, you may be penalized the cost of allocating a new array and copying. – Dave Newton Nov 15 '11 at 17:32
1

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

soulcheck
  • 36,297
  • 6
  • 91
  • 90
  • 5
    Nooooo! Don't say Java is pass-by-reference, you'll get torn to shreds by purists! Java is strictly pass-by-value, but what gets passed for non-primitives is the value of the reference. – G_H Nov 15 '11 at 17:31
  • let's hope they're not lukring around here :) – soulcheck Nov 15 '11 at 17:35
  • What makes you say that objects are passed by reference in Java? I am no expert on the subject, but I can say with 100% confidence that you are terribly wrong! http://download.oracle.com/javase/tutorial/java/javaOO/arguments.html – darnir Nov 15 '11 at 17:37
  • The thing is, the "reference" in "pass-by-reference" isn't the same "reference" as the one in "reference type" (which `object` and its subclasses are). Damn terminology confusing every second programmer... –  Nov 15 '11 at 17:37
1

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..

Community
  • 1
  • 1
darnir
  • 4,870
  • 4
  • 32
  • 47
  • I'd like a reason on why this was downvoted? Anyone disagrees with what I have mentioned here, please speak up.. I will be happy to clarify, but I am more than sure, that my answer is perfectly correct. – darnir Nov 15 '11 at 17:44
1

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.

Kashyap
  • 15,354
  • 13
  • 64
  • 103