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
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.
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.
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.
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..
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.
Java uses call-by-object semantic, so there is no copying.
Related
If we have to swap two elements in java then we can swap them using a temporary variable.
int temp=a;
a=b;
b=temp;
Also, we can do it by using different ways also but is there any predefined method like C++ that have std::swap()?
In the collection, we have swap() but it only works for the list.
No, there is no pre-defined function that swaps two elements. And for good reason. Java is always pass-by-value. Not like C++, where you can choose whether to give the value or the reference of the variable to the function.
If you want to read more about pass-by-value / pass-by-reference, this answer covers pretty much everything.
No, there is no way to do that without using a temporary variable.
Even C++ implementation of std::swap() uses a temporary variable inside, see here.
If you really want to you can wrap this code in a method and just call it.
This is just for fun but if you really want to swap integers, you can do it like so:
int a = 100;
int b = 25;
a = a + b;
b = a - b;
a = a - b;
I am new to C++ and I am porting over a Java project to C++.
Consider the following Java code, where Piece is a class representing a chess piece:
Piece[][] myPieces = new Piece[8][8];
It creates an array where all the entries are null.
How can I achieve the same thing in C++? I tried:
Piece* myPieces = new Piece[8][8];
But this will create an array with all the entries initialized with the default constructor.
Thanks
Edit: I want the C++ code to be efficient/elegant and I do not care nor wnant to copy paste from Java to C++. I am happy to heavily modify the code structure if needed.
Edit 2: The code is for chess programm, the size of the array will never change and performance is critical.
The simplest way to declare an 8x8 array of optional objects in C++ is like so:
boost::optional<Piece> myPieces[8][8];
The boost::optional type represents an optional object (like your nullable references in Java) that doesn't have all the pitfalls of using pointer types. It should be available as part of the standard library in the next few years.
You may prefer to use the std::array type, which is an encapsulation of fixed-size arrays that allows them to be treated as first-class citizens and also provides a nicer interface:
std::array<std::array<boost::optional<Piece>, 8>, 8> myPieces;
If you want to be able to resize your arrays at run-time, consider std::vector instead.
As you want it performant, and right for C++ instead of a dumb translation, how about this:
Use a size-1 POD-type for piece.
Add all the convenience-methods you might want to it:
struct Piece {
unsigned char value;
constexpr Piece() : value() {}
constexpr operator bool() const {return !value;}
constexpr bool empty() const {return *this;};
constexpr bool black() const {return value&0x80;}
constexpr bool white() const {return value && !black();}
constexpr unsigned piece() const {return value & 0x7f;}
};
Now that would be an equivalent raw array:
Piece board[8][8];
Or use std::array:
#include <array>
std::array<std::array<Piece, 8>, 8> board;
The answer depends, because contrary to Java, in C++ you have different ownership semantics and object lifetime management (the two go hand in hand).
If you want to model objects similar to java, you would write:
using PiecePtr = std::shared_ptr<Piece>;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
The shared_ptr has similar semantics to a java object (pass it around wherever and it's lifetime is guaranteed as long as there are references to it).
If you want to model observed objects (i.e. the array doesn't own them), you should write:
using PiecePtr = Piece*;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
This ensures that when the Pieces object gets destroyed, the actual pieces themselves remain in memory.
If you want to model unique objects, owned by the Pieces array, you should use:
using PiecePtr = std::unique_ptr<Piece>;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
This ensures that when the Pieces object gets destroyed, the actual pieces themselves get destroyed as well.
In C++ you'd do something like:
std::vector<std::vector<std::unique_ptr<Pieces>>> myPieces;
Semantically equivalent would be:
Piece* myPieces[8][8]
as java only knows objects on the heap, pointers.
As Piece probably is not a final class, but has King, Queen, this is the way to go.
In c++, newly created object (even in array) is created with default constructor. That's one of the important differences with java. If you want to call constructors individually, just use vector of vectors and add each one of them.
I have no experience with java but I believe from what I got that this could be a good replacement in C++:
std::array<std::array<unique_ptr<foo>, 8>, 8> arr = {};
if(arr[2][3].get() == nullptr) // Can check for null elements
std::cout << "this is null";
arr[3][4].reset(new foo()); // Initialize an element
smart pointer avoids memory leaks
std::array provides performances comparable to a normal C array
aggregate initialization provides each pointer a null value
fixed size as the java array
So you want to make a Chess engine and performance is critical. There are several online tutorials for this. Speed is important for a Chess AI so it can consider more moves per second, but you may need to sacrifice elegance for that.
You can either store the piece values in the board array directly, or store the pieces in a separate backing array and create the board as pointers to these pieces. There are some advantages to the second approach which I can't remember right now.
std::array<std::array<Peice *, 8>, 8> Board;
std::array<Piece, 32> Pieces;
You can represent an empty cell as a null pointer.
If you want everything in the same array, you can simply use
std::array<std::array<Peice, 8>, 8> Board;
But you will need to create a "dummy" piece value to represent an empty cell.
Note there is no dynamic memory allocation and the data is compact in memory so better cache performance.
Piece could be an enum or a struct with some useful getter functions, such as IsWhite.
In C++, you have to declare as:
Piece *** myPieces;
then, allocate as:
myPieces = new Piece **[8];
then,
for (int i = 0; i < 8; i++) {
myPieces[i] = new Piece *;
}
Now, if you do,
myPieces[0][0] = new Piece(); // C++, calls default constructor of Piece
In Java,
Piece[][] myPieces;
myPieces = new Piece[8][8];
now, if you do,
myPieces[0][0] = new Piece(); // Java, calls default constructor of Piece
Since you have 8x8 known already, you may also declare as (in C++):
Piece * myPieces[8][8]; // 64 pointers preallocated as 8 rows, 8 cols
then,
Now, if you do,
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
myPieces[i][j] = new Piece(); // or new Pawn or new Knight etc, subclass of Piece
}}
or allocate as needed e.g.
myPieces[0][0] = new Piece(); // or new Pawn or new Knight etc, subclass of Piece
So for my research group I am attempting to convert some old C++ code to Java and am running into an issue where in the C++ code it does the following:
method(array+i, other parameters)
Now I know that Java does not support pointer arithmetic, so I got around this by copying the subarray from array+i to the end of array into a new array, but this causes the code to run horribly slow (I.e. 100x slower than the C++ version). Is there a way to get around this? I saw someone mention a built-in method on here, but is that any faster?
Not only does your code become slower, it also changes the semantic of what is happening: when you make a call in C++, no array copying is done, so any change the method may apply to the array is happening in the original, not in the throw-away copy.
To achieve the same effect in Java change the signature of your function as follows:
void method(array, offset, other parameters)
Now the caller has to pass the position in the array that the method should consider the "virtual zero" of the array. In other words, instead of writing something like
for (int i = 0 ; i != N ; i++)
...
you would have to write
for (int i = offset ; i != offset+N ; i++)
...
This would preserve the C++ semantic of passing an array to a member function.
The C++ function probably relied on processing from the beginning of the array. In Java it should be configured to run from an offset into the array so the array doesn't need to be copied. Copying the array, even with System.arraycopy, would take a significant amount of time.
It could be defined as a Java method with something like this:
void method(<somearraytype> array, int offset, other parameters)
Then the method would start at the offset into the array, and it would be called something like this:
method(array, i, other parameters);
If you wish to pass a sub-array to a method, an alternative to copying the sub-array into a new array would be to pass the entire array with an additional offset parameter that indicates the first relevant index of the array. This would require changes in the implementation of method, but if performance is an issue, that's probably the most efficient way.
The right way to handle this is to refactor the method, to take signature
method(int[] array, int i, other parameters)
so that you pass the whole array (by reference), and then tell the method where to start its processing from. Then you don't need to do any copying.
THERE ARE ISSUES WTIH AN UNDERSTANDING OF Java IN THIS QUESTION. AS THE AUTHOR, I HAVE KEPT THE ORIGINAL QUESTION INTACT AS THE ANSWERS DO AN EXCELLENT JOB OF CLEARING UP THOSE ISSUES
Please, feel free to make changes to below question in order to improve its quality as a pedagogical tool
I have a JAVA class containing one method, the method receives an array object of integers (as you can see in the code); however, in JAVA, everything is pass[ed]-by-value - a well established fact, i.e. overwriting an object or primitive type passed as an argument cannot happen using a local scope object or p. type.
In other words, in order to change an object (primitive or reference) in Java, one must access the data member (or "attribute") directly or indirectly via a member function (or "method") that has the authority to change the attribute. Simply, the method must have an effect.
The other method for changing the value of an object is to return a value via a function and set the original object to the returned value.
Here is my code (and question to follow):
CODE FRAG. I:
public class BlockSort
{
public static void sort(Block [] blocks)
{
boolean sorted = false;
int length = blocks.length;
while(!sorted)
{
sorted = true;
for (int i = 1; i < length; i++)
{
if (blocks[i - 1].width > array[i].width)
{
Block tempBlock = blocks[i - 1];
blocks[i - 1] = blocks[i];
blocks[i] = tempBlock;
}
else if ((blocks[i - 1].width == array[i].width) && (blocks[i - 1].length > array[i].length))
{
Block tempBlock = blocks[i - 1];
blocks[i - 1] = blocks[i];
blocks[i] = tempBlock;
}
}
length = length - 1;
}
}
Essentially, in a very minimalistic sense, the above code functions the same way as this [NOTE: this statement is not true, see answers):
CODE FRAG. 2:
public myClass
{
public void doesNothing(int someParameter)
{
someParameter = someParameter - 1;
}
}
So, here is my question: without a return type, any value passed to above code will not really do anything, correct? In other words, it has no way of modifying what's passed to it with any real clout (because any modifications are function scope).
I am maintaining that the fragment is not testable
You are absolutely right: changes to parameters of primitive and immutable types cannot be detected from the outside; nor should they be.
[the second code fragment] has no way of modifying what's passed to it
That is also true. Moreover, it may not be possible at all - consider this call:
mc.doesNothing(2*a*a + 3*b + c);
The value passed in to doesNothing is computed from three variables, so there is nothing in the caller that could be modified,
In your original code fragment int someParameter is local to the implementation of doesNothing method - in the same sense that local variables are invisible from outside of the method. Testing it does not make any more sense than "testing" changes to any other local variable of a method.
The other code fragment (CODE FRAG. I), however, is different, because Java arrays are neither primitive nor immutable:
public static void sort(Block [] blocks) {
// Any change to the content of blocks will be visible to the caller
}
Therefore, the changes performed to the blocks array inside the method will be visible to the caller, in the same way that the callers would see changes to any other mutable object.
Java is pass-by-value, but objects and arrays are reference types. The array you pass into sort will be the same array you get out (that is, it'll be in the same place in memory), but the things inside the array may be different.
The BlockSort.sort method does have an effect. It gets passed a reference to a Block [] by value. This does not mean it cannot change the array contents.
If you call it for example with BlockSort.sort(myArray) the variable myArray will on return point to the same array instance. But the content of the array may be changed.
what I am asking ultimately is whether or not the above code is testable
Yes, it is. The code you've posted moves elements around inside the blocks array, and you can certainly test whether the items are sorted once the method returns
Block[] blocks = createBlocks();
BlockSort.sort(blocks);
for(int i = 1; i < blocks.length; i++) {
assert blocks[i].width < blocks[i-1].width;
}
Okay, so, I am going to amalgamate the answers written in response to the original question (because there are a lot of good fragments of information in all of the responses that need to be put together).
THREE ISSUES ARE PRESENT
ISSUE no. 1 Pass-by-value or Pass-by-Reference
Essentially, the above question stems from a - seemingly pervasive - lack of understanding or confusion surrounding how Java's pass-by-value works. Objects in Java are indeed pass[ed]-by-value; however, what is passed by value is the reference to the object, i.e. the value behaves somewhat like a pointer in C++ (that may be untrue, but it seems that way). So, the argument received by the parameter is in fact a value, but the value contains - in thought - a reference to the object:
public static void sort(Block [] blocks)
{
// CODE
}
This is not the case for primitive types. Primitive types pass a copy of their value to the parameter, so they are pass-by-value:
public void doesNothing(int someParameter)
{
// CODE
}
ISSUE no. 2: Arrays Are a Reference Type
An array is a reference type object in Java (as it is in other languages); therefore, when an array is passed, no return statement is need to modify its content. Integers - int are primitive type.
ISSUE no. 3: The Two Code Fragments In the Initial Questions (re-posted)
The two code fragments are indeed behaving differently. The first fragment is passing around values referring to a reference type. The second fragment is passing around values (or copies of values) of primitive type.
Therefore, the first code fragment has an effect, while the second does not
I need to pass a dynamic list of primitives to a Java method. That could be (int, int, float) or (double, char) or whatever. I know that's not possible, so I was thinking of valid solutions to this problem.
Since I am developing a game on Android, where I want to avoid garbage collection as much as possible, I do not want to use any objects (e.g. because of auto boxing), but solely primitive data types. Thus a collection or array of primitive class objects (e.g. Integer) is not an option in my case.
So I was thinking whether I could pass a class object to my method, which would contain all the primitive vales I need. However, thats neither a solution to my problem, because as said the list of primitives is variable. So if I would go that way in my method I then don't know how to access this dynmic list of primitives (at least not without any conversion to objects, which is what I want to avoid).
Now I feel a bit lost here. I do not know of any other possible way in Java how to solve my problem. I hope that's simply a lack of knowledge on my side. Does anyone of you know a solution without a conversion to and from objects?
It would perhaps be useful to provide some more context and explain on exactly what you want to use this technique for, since this will probably be necessary to decide on the best approach.
Conceptually, you are trying to do something that is always difficult in any language that passes parameters on a managed stack. What do you expect the poor compiler to do? Either it lets you push an arbitrary number of arguments on the stack and access them with some stack pointer arithmetic (fine in C which lets you play with pointers as much as you like, not so fine in a managed language like Java) or it will need to pass a reference to storage elsewhere (which implies allocation or some form of buffer).
Luckily, there are several ways to do efficient primitive parameter passing in Java. Here is my list of the most promising approaches, roughly the order you should consider them:
Overloading - have multiple methods with different primitive arguments to handle all the possible combinations. Likely to be the the best / simplest / most lightweight option if there are a relatively small number of arguments. Also great performance since the compiler will statically work out which overloaded method to call.
Primitive arrays - Good way of passing an arbitrary number of primitive arguments. Note that you will probably need to keep a primitive array around as a buffer (otherwise you will have to allocate it when needed, which defeats your objective of avoiding allocations!). If you use partially-filled primitive arrays you will also need to pass offset and/or count arguments into the array.
Pass objects with primitive fields - works well if the set of primitive fields is relatively well known in advance. Note that you will also have to keep an instance of the class around to act as a buffer (otherwise you will have to allocate it when needed, which defeats your objective of avoiding allocations!).
Use a specialised primitive collection library - e.g. the Trove library. Great performance and saves you having to write a lot of code as these are generally well designed and maintained libraries. Pretty good option if these collections of primitives are going to be long lived, i.e. you're not creating the collection purely for the purpose of passing some parameters.
NIO Buffers - roughly equivalent to using arrays or primitive collections in terms of performance. They have a bit of overhead, but could be a better option if you need NIO buffers for another reason (e.g. if the primitives are being passed around in networking code or 3D library code that uses the same buffer types, or if the data needs to be passed to/from native code). They also handle offsets and counts for you which can helpful.
Code generation - write code that generates the appropriate bytceode for the specialised primitive methods (either ahead of time or dynamically). This is not for the faint-hearted, but is one way to get absolutely optimal performance. You'll probably want to use a library like ASM, or alternatively pick a JVM language that can easily do the code generation for you (Clojure springs to mind).
There simply isn't. The only way to have a variable number of parameters in a method is to use the ... operator, which does not support primitives. All generics also only support primitives.
The only thing I can possibly think of would be a class like this:
class ReallyBadPrimitives {
char[] chars;
int[] ints;
float[] floats;
}
And resize the arrays as you add to them. But that's REALLY, REALLY bad as you lose basically ALL referential integrity in your system.
I wouldn't worry about garbage collection - I would solve your problems using objects and autoboxing if you have to (or better yet, avoiding this "unknown set of input parameters" and get a solid protocol down). Once you have a working prototype, see if you run into performance problems, and then make necessary adjustments. You might find the JVM can handle those objects better than you originally thought.
Try to use the ... operator:
static int sum (int ... numbers)
{
int total = 0;
for (int i = 0; i < numbers.length; i++)
total += numbers [i];
return total;
}
You can use BitSet similar to C++ Bit field.
http://docs.oracle.com/javase/1.3/docs/api/java/util/BitSet.html
You could also cast all your primitives to double then just pass in an array of double. The only trick there is that you can't use the boolean type.
Fwiw, something like sum(int... numbers) would not autobox the ints. It would create a single int[] to hold them, so there would be an object allocation; but it wouldn't be per int.
public class VarArgs {
public static void main(String[] args) {
System.out.println(variableInts(1, 2));
System.out.println(variableIntegers(1, 2, 3));
}
private static String variableInts(int... args) {
// args is an int[], and ints can't have getClass(), so this doesn't compile
// args[0].getClass();
return args.getClass().toString() + " ";
}
private static String variableIntegers(Integer... args) {
// args is an Integer[], and Integers can have getClass()
args[0].getClass();
return args.getClass().toString();
}
}
output:
class [I
class [Ljava.lang.Integer;