• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

loops that slow down

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a problem with a program thats supposed to create a two dimensional array, and then re-create it 1000 times based on the "neighbours" of each element of the array.
The problem is, the way I've done it, it takes longer to run through each iteration of the loop. I can tell because I've put a "System.out.prinln" command on every loop.
When the arrays are small its not too much of a problem, but when the arrays are 100x100 and get checked 1000 times the whole thing doesnt work.
I probably dont quite understand what I've done: Am I somehow re-creating or copying the array? How else can I do this?
import javax.swing.*;
import java.awt.*;
public class GameOfLife3
{
public int array[][];
public String output;
public GameOfLife3()
{
array = new int[100][100];
output = "";
}

public static void main (String args[])
{

JTextArea outputArea = new JTextArea(20, 60);
outputArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane scroller = new JScrollPane(outputArea);
//create an instance of class GameOfLife3

GameOfLife3 game3 = new GameOfLife3();
//call method that initialises elements of 2d array
game3.initArray(game3.array);
game3.output = game3.writeArray(game3.array, game3.output);
//call method that checks the values of the "neighbours" of elements
//in 2d array and then checks whether they should live or die.
//call method that puts these values in a String. Loop 1000x
for(int count = 0; count <=1000; count++)
{
game3.checkNeighbour(game3.array);
game3.output = game3.writeArray(game3.array, game3.output);
}
outputArea.setText(game3.output);
//Display scrollable JTextArea containing the string "output"
JOptionPane.showMessageDialog(null, scroller,
"Game Of Life 3", JOptionPane. PLAIN_MESSAGE);
System.exit(0);
} //end main

//method initArray: initialises 2d-array
//to random int values 1 & 0
public void initArray( int array2[][])
{
for(int row = 0; row < array2.length; row ++)
{

for(int column = 0; column < array2[row].length; column++)
{
array2[row][column] = 0 + (int)(Math.random()*2);


}


}

}
//method check Neighbour does 3 things:
//1. checks values of "neighbour" elements in array
//2. creates new array according to game of life rules
//3. places values ofnew array back in first array
public void checkNeighbour(int array2[][])
{
int array3[][] = new int[100][100];
int neighbour = 0;
for(int row = 0; row < array2.length; row ++)
{
for(int column = 0; column < array2[row].length; column++)
{

if(row ==0 && column == 0)
{
if( array2[row][column+1]==1)
neighbour++;

if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;


}
if(row == 0 && column > 0 && column < array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;

if(array2[row][column+1]==1)
neighbour++;

if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;


}

if(row == 0 && column == array2.length-1)
{

if(array2[row][column-1]==1)
neighbour++;
if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;


}
if(column == 0 && row > 0 && row < array2.length-1)
{
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;

}
if( column == 0 && row == array2.length-1)
{

if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;


}
if(column == array2.length-1 && row == array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;


}
if(row == array2.length-1 && column > 0 &&
column < array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1] ==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;


}
if(column == array2.length-1 && row >0 &&
row < array2.length -1)
{
if(array2[row+1][column]==1)
neighbour++;

if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row][column-1] ==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;


}

if(column > 0 && column < array2.length-1 &&
row > 0 && row< array2.length-1)
{
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;
if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row][column-1] ==1)
neighbour++;

}
if(array2[row][column] == 0)
{
if(neighbour == 3)
array3[row][column] = 1;
else
array3[row][column] = 0;
}
if(array2[row][column] == 1)
{

if(neighbour == 3 || neighbour == 2)
array3[row][column] = 1;
else
array3[row][column] = 0;
}

neighbour = 0;




}//close loop column


}//close loop row


for(int row = 0; row < array2.length; row ++)
{

for(int column = 0; column < array2[row].length; column ++)
{
array2[row][column] = array3[row][column];
}


}
}

//method writeArray: puts elements of 2d array in string to be displayed
public String writeArray( int array2[][], String output1)
{
for(int row = 0; row < array2.length; row ++)
{
for(int column = 0; column < array2[row].length; column ++)
{

output1 += array2[row][column];
}

output1 += "\n";


}

output1 += "\n";
for(int count = 0; count <= 100; count ++)
output1+= "-";
output1 += "\n";

return output1;
}
} // end GameOfLife1
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Howdy, Ma'am.
You've been asked before to have a look at our naming policy, and head over here to update your display name. Specifically, we don't allow obviously fictitous names, nor do we allow the first name to be a title. Please be a good little cowgirl and play along, eh? Thanks.
 
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Here you call checkNeighbour() 1001 times (this is an example of the infamous off-by-one error), everytime array gets _copied_ into the method.

First, a new array is created everytime the programm enters checkNeighbour(). This results in memory allocation for 38 MB (1000 times, a 100 * 100 * 4 = 38 ), wich gets freed after the method returns. Not bad for such a small programm!
At the end of checkNeighbour(), you copy the hole array3 into array2. Try to use System.arraycopy() to improve that. Take a look at this to find out how it works.
 
Masha Stekker
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks! That helps a lot
 
Masha Stekker
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good, so far I seem to have managed to carry out your suggestions with succsess. But it seems that the big problem that slows down the loops is in the way I am displaying the information, because when I comment out the "writeArray" method the problem goes away. So I geuss I'll have to have another look at how Ive done that.
I dont really understand enough of how the mechanics of it works to understan why the way I did it makes it slow down. Any ideas?
 
Tobias Hess
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

First, drop the parameters:
public String writeArray()
Second, replace every array2 with array and output1 with output.
The method writeArray() belongs to the same object wich holds the data. So it can access the data directly, there's no need to pass it arround with parameters.
If this doesn't make sense to you, think of an this.array and this.output -but don't write it, the compiler does it implicitly for you.
How is it going?
Tobias
 
Masha Stekker
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, Thanks! I did those things. Very illuminating.
But I still have my slowing down problem.
Have a look - maybe I misunderstood what you meant with some things. One thing I did was to move the array declaration and initialisation from the method checkNeighbour to the beginning, where the class starts. I hoped that this would help with the memory problem you mentioned, but possibly I misunderstood?
Have look if you dont mind spending more time on this one!
import javax.swing.*;
import java.awt.*;
public class GameOfLife3
{
public int array[][];
public int array3[][];
public String output;

public GameOfLife3()
{
array = new int[10][10];
array3 = new int[10][10];
output = "";
}

public static void main (String args[])
{

JTextArea outputArea = new JTextArea(20, 60);
outputArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane scroller = new JScrollPane(outputArea);
//create an instance of class GameOfLife3

GameOfLife3 game3 = new GameOfLife3();
//call method that initialises elements of 2d array
game3.initArray(game3.array);
game3.output = game3.writeArray();

//call method that checks the values of the "neighbours" of elements
//in 2d array and then checks whether they should live or die.
//call method that puts these values in a String. Loop 1000x
for(int count = 0; count <100; count++)
{
game3.checkNeighbour(game3.array);
game3.output = game3.writeArray();
}
outputArea.setText(game3.output);
//Display scrollable JTextArea containing the string "output"
JOptionPane.showMessageDialog(null, scroller,
"Game Of Life 3", JOptionPane. PLAIN_MESSAGE);
System.exit(0);
} //end main

//method initArray: initialises 2d-array
//to random int values 1 & 0
public void initArray( int array2[][])
{
for(int row = 0; row < array2.length; row ++)
{

for(int column = 0; column < array2[row].length; column++)
{
array2[row][column] = 0 + (int)(Math.random()*2);


}


}

}
//method check Neighbour does 3 things:
//1. checks values of "neighbour" elements in array
//2. creates new array according to game of life rules
//3. places values ofnew array back in first array
public void checkNeighbour(int array2[][])
{

int neighbour = 0;

for(int row = 0; row < array2.length; row ++)
{
for(int column = 0; column < array2[row].length; column++)
{

if(row ==0 && column == 0)
{
if( array2[row][column+1]==1)
neighbour++;

if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;


}
if(row == 0 && column > 0 && column < array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;

if(array2[row][column+1]==1)
neighbour++;

if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;


}

if(row == 0 && column == array2.length-1)
{

if(array2[row][column-1]==1)
neighbour++;
if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;


}
if(column == 0 && row > 0 && row < array2.length-1)
{
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;

}
if( column == 0 && row == array2.length-1)
{

if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;


}
if(column == array2.length-1 && row == array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;


}
if(row == array2.length-1 && column > 0 &&
column < array2.length-1)
{
if(array2[row][column-1]==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1] ==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;


}
if(column == array2.length-1 && row >0 &&
row < array2.length -1)
{
if(array2[row+1][column]==1)
neighbour++;

if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row][column-1] ==1)
neighbour++;
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;


}

if(column > 0 && column < array2.length-1 &&
row > 0 && row< array2.length-1)
{
if(array2[row-1][column-1]==1)
neighbour++;
if(array2[row-1][column]==1)
neighbour++;
if(array2[row-1][column+1]==1)
neighbour++;
if(array2[row][column+1]==1)
neighbour++;
if(array2[row+1][column+1]==1)
neighbour++;
if(array2[row+1][column]==1)
neighbour++;
if(array2[row+1][column-1]==1)
neighbour++;
if(array2[row][column-1] ==1)
neighbour++;

}
if(array2[row][column] == 0)
{
if(neighbour == 3)
array3[row][column] = 1;
else
array3[row][column] = 0;
}
if(array2[row][column] == 1)
{

if(neighbour == 3 || neighbour == 2)
array3[row][column] = 1;
else
array3[row][column] = 0;
}

neighbour = 0;

System.out.println(column);




}//close loop column


System.out.println("row" + row);

}//close loop row




System.arraycopy(array3, 0, array2, 0, 10);
}

//method writeArray: puts elements of 2d array in string to be displayed
public String writeArray( )
{
for(int row = 0; row < array.length; row++)
{
for(int column = 0; column < array[row].length; column ++)
{

output += array[row][column];
}

output += "\n";


}

output += "\n";
for(int count = 0; count <= 100; count ++)
output+= "-";
output += "\n";

return output;
}
} // end GameOfLife1
 
Tobias Hess
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm sorry, I'll have to work now. At a first look, I can't see how to do that method better.
BTW, why is performace an issue for this application? How long does it run for 100x100 arrays on your machine?
 
Masha Stekker
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh well - but thanks yet again for your help.
I have to check it again, but at one point my machine never manages to get through the entire program, I think is slows down to a complete stop, so the performance is a bit of an issue! But I'll check it again now that I've made these changes.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic