1
\$\begingroup\$

I am working on optimizing a Wator program. I have a specific question about code, if you are familiar with it. There is a function which takes most of the time. I need your help to improve this particular part of the code.

 // find all neighbouring cells of the given position that contain an animal of the given type public int GetNeighbors(Type type, Point position) { int neighborIndex; int i, j; // counter for the number of cells of the correct type neighborIndex = 0; // look up i = position.X; j = (position.Y + Height-1)%Height; // if we look for empty cells (null) we don't have to check the type using instanceOf if ((type == null) && (Grid[i, j] == null)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } else if ((type != null) && (type.IsInstanceOfType(Grid[i, j]))) { // using instanceOf to check if the type of the animal on grid cell (i/j) is either a shark of a fish // animals that moved in this iteration onto the given cell are not considered // because the simulation runs in discrete time steps if ((Grid[i, j] != null) && (!Grid[i, j].Moved)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } } // look right i = (position.X + 1) % Width; j = position.Y; if ((type == null) && (Grid[i, j] == null)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } else if ((type != null) && (type.IsInstanceOfType(Grid[i, j]))) { if ((Grid[i, j] != null) && (!Grid[i, j].Moved)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } } // look down i = position.X; j = (position.Y + 1) % Height; if ((type == null) && (Grid[i, j] == null)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } else if ((type != null) && (type.IsInstanceOfType(Grid[i, j]))) { if ((Grid[i, j] != null) && (!Grid[i, j].Moved)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } } // look left i = (position.X + Width - 1) % Width; j = position.Y; if ((type == null) && (Grid[i, j] == null)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } else if ((type != null) && (type.IsInstanceOfType(Grid[i, j]))) { if ((Grid[i, j] != null) && (!Grid[i, j].Moved)) { neighbors[neighborIndex] = new Point(i, j); neighborIndex++; } } return neighborIndex; } 
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$
  1. The first thing that I see when I look at your code is that it is UGLY. I appreciate it doesn't affect how well the code works, but it does affect how easy it is to read and if it is hard to read then you are more likely to miss important issues. When you come back to this code in three months it will be like you are new to it. So my first recommendation is adopt a common style for the language you are using and make sure you stick to it. Look at other people's C# code on here, yours looks more like Java than C#.

  2. You have defined neighbourIndex at the top and assigned an initial value to it a few lines later. It is a good idea to always assign a value to a variable when you declare it. To be honest this is less important in C# that C++, but you can still get in nasty situations when you assume an object has been assigned a value and it hasn't.

  3. You have used a nice, descriptive name like neighbourIndex and then gone and used i and j. If I have read the code correctly these are the x and y co-ordinates of a cell. So why not use x and y? Also since you have already used the Point class would it not be a good idea to use the Point class to store i and j in?

  4. In C#, as far as I understand, there is no difference in the speed of execution of x++ and ++x, but in other languages with other compilers this may not be the case (C++ for instance) so I would recommend that if you are doing x++; you get into the habit of doing ++x; because this can sometime be faster for non simple data types. HOWEVER in this case it would be better to do neighbors[neighborIndex++] = new Point(i, j);

  5. I agree with user673679 that there could be a significant amount of optimisation here, you are doing something very similar 4 times, that should scream out to you to be optimised.

And finally a positive, your code is littered with comments and that is brilliant, keep it up. If you decide to make any changes then remember to check that your comments still make sense. Also finish the job off with a nice descriptive comment at the top of the functions to explain what the function does, what the parameters are, what ranges they take and what the function returns. If you really want to go all out, describe the expected pass and fail conditions so that it becomes easy to write tests for the function.

Hope that helps

\$\endgroup\$
3
\$\begingroup\$

It's hard to know exactly what would help without a seeing more code, but here are some things to consider:

If neighbors is a pre-allocated array, do you need new Point(i,j) or can you simply do neighbors.X = i; neighbors.Y = j? You might consider using a standard collection type instead.

It seems like you're using different object types for animals. It would be much simpler to use an enum: enum SquareType { Empty, Fish, Shark }; and then you could compare values instead of using IsInstanceOfType. This would also eliminate the special-case need to check if grid cells or type were null.

There's also quite a lot of duplicated functionality there. All of your direction checks could be merged into a function that took an xOffset and yOffset parameters. Then you could do something like:

int neighborIndex = 0; neighborIndex += CheckNeighbor(-1, 0, type, position); // left neighborIndex += CheckNeighbor(1, 0, type, position); // right neighborIndex += CheckNeighbor(-1, 0, type, position); // up neighborIndex += CheckNeighbor(1, 0, type, position); // down 
\$\endgroup\$
2
  • \$\begingroup\$ I use neighbors to save every position because after this function i choose position randomly. \$\endgroup\$ Commented Oct 27, 2015 at 23:26
  • \$\begingroup\$ Certainly there are lot of duplicate code, and it makes it harder to read, and solve the issue you have. It would be worth that you refactor the code, take the common feature out as @user673679 said. Then it will be easier for to focus on the issue. \$\endgroup\$ Commented Oct 28, 2015 at 7:53

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.