Reputation: 109
I've recently started learning Java and though doing a "Conway's Game of Life" style program would be a good thing to start out with. Everything works fine but I'm having some serious performance issues with this part:
static List<Point> coordList = new ArrayList<Point>();
public int neighbors(int x, int y){
int n = 0;
Point[] tempArray = { new Point(x-1, y-1), new Point(x, y-1), new Point(x+1, y-1),
new Point(x-1, y ), new Point(x+1, y ),
new Point(x-1, y+1), new Point(x, y+1), new Point(x+1, y+1)};
for (Point p : tempArray) {
if (coordList.contains(p))
n++;
}
return n;
}
The method is used when iterating the ArrayList
coordList filled with Points and checking every element how many neighbors they have. When the list size gets to about 10000 Points every cycle takes about 1 seconds and for 20000 Points it takes 7 seconds.
My question is, what would be a more effective way to do this? I know there are several other programs of this kind with source code available too look at, but I wan't do do as much as I can by my self since the point of the project is me learning Java. Also, I don't want to use a regular array because of the limitations.
Upvotes: 2
Views: 1872
Reputation: 38043
Your current code scales in a quadratic manner O(n^2)
. You have only given part of the program. If you look at your whole program there will be a loop that calls neighbors()
and you will see that neighbors()
is called n times. Also the operation contains() is linear in n, so the time is proportional to their product n*n
.
Quadratic scaling is a common problem but can often be reduced to linear by using indexed data structures such as HashSet
.
Upvotes: 1
Reputation: 500317
Performance-wise, I think your best bet is to have a plain numeric (effectively Boolean) array representing the grid. Since this is a learning exercise, I'd start with a simple one-element-per-cell array, and then perhaps progress to packing eight adjacent cells into a single byte.
It is not entirely clear what you mean by "the limitations".
The following has some interesting pointers: Optimizing Conway's 'Game of Life'
Upvotes: 1
Reputation: 328598
If your points are unique, you could store them in a HashSet
instead of an ArrayList
. The contains
method will then become an O(1) operation vs. O(n) in your current setup. That should speed up that section significantly.
Apart from the declaration, your code should remain mostly unchanged as both implement the Collection
interface, unless you call List-specific method such as get(i)
for example.
Upvotes: 1