I’m trying to do a Life simulation in Unity and I’ve run into some severe performance issues, among other problems.
Here are the relevant portions of my code, called in FixedUpdate:
// Compute the next life step:
void UpdateCellMatrix()
{
int n; // Number of adjacent cells alive.
int state;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
// Count living neighbors. Matrix wraps at borders to avoid a bunch of conditional jumps.
n = cellMatrix[i, (j + 1) % height]; // top
n += cellMatrix[(i + 1) % width, (j + 1) % height]; // top right
n += cellMatrix[(i + 1) % width, j % height]; // right
n += cellMatrix[(i + 1) % width, (height + j - 1) % height]; // bottom right
n += cellMatrix[i % width, (height + j - 1) % height]; // bottom
n += cellMatrix[(width + i - 1) % width, (height + j - 1) % height]; // bottom left
n += cellMatrix[(width + i - 1) % width, j % height]; // left
n += cellMatrix[(width + i - 1) % width, (j + 1) % height]; // top left
state = cellMatrix[i, j]; // Get state of cell.
if (state == 1) // If cell is alive...
{
if ((n < 2) || (n > 3)) { state = 0; } // If cell is alive and has less than 2 or more than 3 alive neighbors, kill it.
}
else // If cell is dead...
{
if (n == 3) { state = 1; } // If cell is dead and has exactly 3 living neighbors, kill it.
}
newMatrix[i, j] = state; // Record new cell state.
}
}
swapMatrix = cellMatrix;
cellMatrix = newMatrix; // Swap array pointers.
newMatrix = swapMatrix;
}
// Draws the cell matrix to the texture.
void DrawCellMatrix()
{
int index = 0; // ints in Unity are 32 bit.
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
if (cellMatrix[i, j] == 0) { newColors[index] = Color.black; } else { newColors[index] = Color.white; }
index++;
}
}
tex.SetPixels32(newColors); // Second parameter is mip level?
tex.Apply(); // Update texture on sprite.
}
I have already run the profiler and confirmed that 95% of the time the code is in the UpdateCellMatrix() function. I assume the texture update code is almost as fast as it can be made. I mean I can probably reduce those two loops to one, but I’m guessing the bottleneck there is updating the texture on the card not the speed of that loop.
I should mention that I am running this within the editor. I do not know if running within the editor the code will execute slower.
I also do not know if there is some sort of debug mode being enabled somewhere causing code execution to slow down. I am new to Unity.
I am however not new to programming, just C#, and I know using 2D arrays is bad for performance and having a bunch of modulos in there is also bad. I was just trying to get this up and running as a proof of concept that is easy to understand and could be easily modified before I went crazy with optimizations.
Still, even without optimizations this should not run this slow. It looks like its running at like 4fps. And a friend has run the same simulation on a a crappy old linux box in matlab of all things, and he’s getting 200fps.
So what’s going on here? Is C# interpreted in Unity? Is there some debugger enabled that’s slowing things down and which enables that profiler to work? (It’s slow whether or not I have the profiler window open.) If so, how do I disable that? Or is the code always slow within the editor? I’m going to build the project and check its speed next, but I have my doubts that is going to help.
What I really want to know is:
Is there any way I can speed this up beyond simply optimizing my code? Is something other than my crappy algorithm slowing this way down?
ADDENDUM:
I asked about this on Reddit and I got a bunch of irrelevant responses which missed the point so I want to clarify some things:
- I am not looking to improve the frame rate. I am looking to increase the speed of the simulation.
Slowing down the simulation to boost the frame rate misses the point. And co-routines will not help here.
(Well I mean, maybe if they run on a separate core they might? The code’s still super slow though. I don’t know much about how co-routines work.)
- I am aware the code is unoptimized. I am not looking for suggestions on how to move some of the calculations out of my loop.
I am looking for an explanation for why similar unoptimized code runs 50x faster in Matlab on a 10-15 year old Linux box.
The questions I need answered are:
-
Is C# in Unity in the general vicinity of being as fast as compiled C++? Or is it interpreted at runtime like Javascript in a browser?
-
Is there some debugger in Unity that slows things down that I can disable?
-
Will my code run much slower when I am running it in the editor versus building it as a final project?