Sorting Implementation, same test case - java

i have sth like: ( X - different algorithms)
public class XAlgorithm{
sort(List l){...}
}
In testClass it present as follows:
ArrayList array = new ArrayList(...); // original array
public static void main(String[]args){
AlgorithmsTest at = new AlgorithmsTest();
at.testInsertSort();
// when add at.array.printAll() - method printing all elements, there are no changes to original array what I want
at.testBubbleSort();
at.testSelectSort();
at.testShellSort();
}
testBubbleSort{
...
ArrayList arrayBubble = new ArrayList(testBubble.sort(array));
...
}
Problem is my result ( time measured by System.currentTimeMilis() ) is different when i launch for ex. two times in a row the same algorithm, it's also strange because even when I done copying in every method ( by putting all new Elements into new array and then operate on it) still works wrong. Time is always greatest for first algorithm in main no matter which one it is.
I even controlled array between every algorithm ( like //comment in code above) and it is right - no changes to it, so where is the problem :/ ?
Thanks in advance

Even though you stated you're making a copy of the array, it sounds like you're sorting in place and then making a copy of the array.
Therefore, the first time is going to take longest, but all subsequent runs have less work to do because the array is "sorted".
It also seems to say that your sort algorithms have bugs in it, such that you're getting close on the first sort (or it is right) but then a subsequent sort is finding a corner case, causing a slight variation in the sorted array. I'd be analyzing my sort methods and make sure they're working as you intended.

Related

How do I use a deep copy efficiently?

I am writing a class GenerateNeighbours in which an initial solution Sol is passed to the constructor. A number of "neighbours" of this solution is to be computed. In order to make sure that my initial solution does not change, I am making a deep copy of the initial solution every iteration.
Also, I am making use of an arraylist S_Comp which was created using generateSComp(). At the start each iteration, this version of S_Comp is to be used. Therefore, I am not calling generateSComp() each iteration, as I figured that this would be unnecessary and it would require an excessive amount of time.
Since S_Comp changes within each iteration and I want to make sure that I start with the same S_Comp each iteration, I am also using a deep copy for this. However, I feel like my approach is not so efficient, since the running time of my program barely improved with respect to calling generateSComp every iteration.
Below you can find the code that I am talking about:
public GenerateNeighbours(DataFile testDataFile, ArrayList<Route> Sol, Random randomGen) throws IOException
{
solution = (ArrayList<Route>) DeepCopy.copy(Sol);
S_Comp = new ArrayList<MyNodesData>();
S_Comp = generateSComp(testDataFile, solution, S_Comp);
ArrayList<MyNodesData> originalS_Comp = (ArrayList<MyNodesData>) DeepCopy.copy(S_Comp);
rewards = new ArrayList<Integer>();
neighbours = new ArrayList<ArrayList<Route>>();
//---------Generating neighborhood solutions---------
for(int i=0; i<parameterSet.getBeta(); i++)
{
solution = (ArrayList<Route>) DeepCopy.copy(Sol); <---- making a deep copy every iteration
S_Comp = (ArrayList<MyNodesData>) DeepCopy.copy(originalS_Comp); <---- making a deep copy every iteration
// S_Comp = new ArrayList<MyNodesData>();
// generateSComp(testDataFile, solution, S_Comp); <------- This is what should be unnecessary since S_Comp is the same at the start of every iteration
step1to6(i);
rewards.add(getSolutionReward(solution));
neighbours.add(solution);
}
}
Since I am making two deep copies every iteration, I feel like my program is rather inefficient. Does anybody have a suggestion on how to use my deep copies more efficiently? Or is this just the way it should be done?
(For the DeepCopy class I used the one as suggested at http://javatechniques.com/blog/faster-deep-copies-of-java-objects/)

Optimizing Java Array Copy

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.

Preventing allocation for ArrayList iterators in Java

So I am part way through writing my first game on Android and after watching a lengthy presentation on optimising for games, I have been checking my allocations. I have managed to get rid of all in-game allocations apart from ones made my ArrayList when it creates an implicit iterator for the for(Object o : m_arrayList) convention.
There are a fair few of these iterations/allocations since all of my game objects, ai entities etc. are stored in these for their ease of use.
So what are my options?
I could, theoretically specify sensible upperbounds and use arrays, but I like the features of ArrayList such as exists and remove that keep code clean and simple.
Override ArrayList and provide my own implementation of iterator() that returns a class member rather than allocating a new iterator type each time it is used.
I would prefer to go for option 2 for ease of use, but I had a little go at this and ran into problems. Does anyone have an example of what I described in option 2 above? I was having problems inheriting from a generic class, type clashes apparently.
The second question to this then is are there any other options for avoiding these allocations?
And I guess as a bonus question, Does anyone know if ArrayList preallocates a number of memory slots for a certain amount (specified either in the ctor or as some shiftable value) and would never need to do any other allocations so long as you stay within those bounds? Even after a clear()?
Thanks in advance, sorry there is so much there but I think this information could be useful to a lot of people.
Use positional iteration.
for ( int i = 0, n = arrayList.size( ); i < n; ++i )
{
Object val = arrayList.get( i );
}
That's how it was done before Java 5.
For preallocation.
ArrayList arrayList = new ArrayList( numSlots );
or at runtime
arrayList.ensureCapacity( numSlots );
And for a bonus -> http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
I'll answer the bonus question first: Yes, ArrayList does pre-allocate slots. It has a constructor that takes the desired number of slots as an argument, e.g. new ArrayList<Whatever>(1000). clear does not deallocate any slots.
Returning a shared iterator reference has a few problems. The main problem is that you have no way of knowing when the iterator should be reset to the first element. Consider the following code:
CustomArrayList<Whatever> list = ...
for (Whatever item : list) {
doSomething();
}
for (Whatever item : list) {
doSomethingElse();
}
The CustomArrayList class has no way of knowing that its shared iterator should be reset between the two loops. If you just reset it on every call to iterator(), then you'll have a problem here:
for (Whatever first : list) {
for (Whatever second : list) {
...
}
}
In this case you do not want to reset the iterator between calls.
#Alexander Progrebnyak's answer is probably the best way to iterate over a list without using an Iterator; just make sure you have fast random access (i.e. don't ever use a LinkedList).
I'd also like to point out that you are getting into some pretty heavy micro-optimization here. I'd suggest that you profile your code and find out if allocating iterators is a genuine problem before you invest much time in it. Even in games you should only optimize what needs optimizing, otherwise you can spend many, many days shaving a few milliseconds off a minute-long operation.

Calling a method n times: should I use a converted for-each loop or a traditional for loop?

Given the need to loop up to an arbitrary int value, is it better programming practice to convert the value into an array and for-each the array, or just use a traditional for loop?
FYI, I am calculating the number of 5 and 6 results ("hits") in multiple throws of 6-sided dice. My arbitrary int value is the dicePool which represents the number of multiple throws.
As I understand it, there are two options:
Convert the dicePool into an array and for-each the array:
public int calcHits(int dicePool) {
int[] dp = new int[dicePool];
for (Integer a : dp) {
// call throwDice method
}
}
Use a traditional for loop:
public int calcHits(int dicePool) {
for (int i = 0; i < dicePool; i++) {
// call throwDice method
}
}
My view is that option 1 is clumsy code and involves unnecessary creation of an array, even though the for-each loop is more efficient than the traditional for loop in Option 2.
At this point, speed isn't important (insert premature-optimization comment ;). What matters is how quickly you can understand what the code does, which is to call a method dicePool times.
The first method allocates an array of size dicePool and iterates through its values, which happens to run the loop body dicePool times (I'll pretend you meant int instead of Integer to avoid the unrelated autoboxing issue). This is potentially inefficient for the computer running the code, but more importantly it's inefficient for the human reading the code as it's conceptually distant from what you wanted to accomplish. Specifically, you force the reader to think about the new array you've just made, AND the value of the variable a, which will be 0 for every iteration of the loop, even though neither of those are related to your end goal.
Any Java programmer looking at the second method will realize that you're executing the loop body dicePool times with i 'counting up' to dicePool. While the latter part isn't especially important, the beginning is exactly what you meant to do. Using this common Java idiom minimizes the unrelated things a reader needs to think about, so it's the best choice.
When in doubt, go with simplicity. :D
Why would you need to allocate an array to loop over a variable that can be safely incremented and used without any need of allocation?
It sounds unecessarily inefficient. You can need to allocate an array if you need to swap the order of ints but this is not the case. I would go for option 2 for sure.
The foreach is useful when you want to iterate on a collection but creating a collection just to iterate over it when you don't need it is just without sense..
(2) is the obvious choice because there's no point in creating the array, based on your description. If there is, of course things change.
What makes you think that the for-each loop is more efficient?
Iterating over a set is very likely less efficient than a simple loop and counter.
It might help if you gave more context about the problem, specifically whether there's more to this question than choosing one syntax over the other. I am having trouble thinking of a problem to which #1 would be a better solution.
I wouldn't write the first one. It's not necessary to use the latest syntax in every setting.
Your instinct is a good one: if it feels and looks clumsy, it probably is.
Go with #2 and sleep at night.

Recursion Question : Revision

My slides say that:
A recursive call should always be on a smaller data structure than the current one
There must be a non recursive option if the data structure is too small
You need a wrapper method to make the recursive method accessible
Just reading this from the slides makes no sense, especially seeing as it was a topic from before christmas!
Could anyone try and clear up what it means please?
Thank you
A recurssive call should always be on a smaller data structure than the current one
In general this isn't true but if you are talking about linked lists manipulation with recursion it is. What it is implying is that you need to always be working towards a solution and this usually is dealing with a smaller problem than you started with.
Take for example Quicksort. Each time the function is called it is working with a smaller set of data.
Taking another example of printing a linked list, the next time you call the recursive function the argument should be the tail of the linked list (This code has an error in it, but that leads us to our next point)
void printList(List l){
print(l.head);
printList(l.tail);
}
There must be a non recurssive option if the data structure is too small
This means there should be a base case. The point where the function stops calling itself again.
int factorial(int n){
if ( n == 1 ){ //the base case is when n = 1
return 1;
}
return n*factorial(n-1);
}
Going back to the example of printing a linked list, there has to be a case where you only have an empty list left (in which case the function should do nothing). Going back to the code to print a linked list
void printList(List l){
if ( l.empty == true ){ //the base case is when the list l is empty
return;
}
print(l.head);
printList(l.tail);
}
You need a wrapper method to make the recurssive method accessible
I don't know Java, and it isn't really a language designed for recursion, however in many cases your recursive function will have more parameters than the person using the API should be able to see. You might for example want to have a counter in there.
You can have a wrapper function that simplifies the parameters to just what is needed. The wrapper function then calls the real worker function.
An example might be if we have a linked list class that has the recursive function to print the list. Its declaration would look something like this:
void printList(List l);
However as it is a class method, to someone using the API it doesn't make much sence to have to do this:
myList.printList(myList);
So a wrapper function could be created that doesn't have any paramters which then calls the code that does the work.
void printList(){
doPrintList(this); //pass in the List object as the first argument
}
Then all the programmer using the API has to do is:
myList.printList();

Categories

Resources