- Home /
Ways to minimize Object.stelemref() calls (low level)
I am working on optimizing my A* algorithm in C#. In the background I have written a min priority queue that uses a heap as its backend data structure.
I have gotten the optimization basically as far down as I can get it with algorithmic and refactoring changes, but have now hit a spot where the Unity profiler is telling me the most called method is one I don't have a direct way to optimize.
As an example, when moving a character from the farthest possible corner to another on my map, the profiler is telling me that my FindPath method is taking 83.7% of the CPU time that frame. The two methods within that that use the most time are my Heap.Insert() and Heap.Remove() methods. Inside each of these Insert and Remove calls the profiler shows only one method being called a total of 60000+ times and that is Object.stelemref().
What exactly about my C# is causing this to be called in the background so many times? I am guessing this is an array/memory management issue, but have no idea how to reduce the number of times it is being called. Here is the code from the two methods in question:
(Note: in my sample, heap is an array with 250000 slots)
public override void Insert(Cell cell) {
int current = count;
while (current > 0) {
int parent = (current - 1) / 2;
// Compare the new item with its current parent
if (cell.Node.FScore < heap[parent].Node.FScore) {
// If less "swap" them (swap parent item and current index)
heap[current] = heap[parent];
current = parent;
} else {
// If not, place in current spot, we are done
break;
}
}
heap[current] = cell;
count++;
}
public override Cell Remove() {
count--;
// Save the top item and decrement the count
Cell top = heap[0];
heap[0] = heap[count];
// Perform the heapify
int current = 0;
while (current < count) {
int smallest = current;
int left = smallest * 2 + 1;
int right = left + 1;
if (left < count && heap[left].Node.FScore < heap[smallest].Node.FScore) {
smallest = left;
}
if (right < count && heap[right].Node.FScore < heap[smallest].Node.FScore) {
smallest = right;
}
if (smallest == current) {
break;
}
Cell swap = heap[smallest];
heap[smallest] = heap[current];
heap[current] = swap;
current = smallest;
}
return top;
}
Answer by Bunny83 · Sep 10, 2013 at 06:42 AM
Stelem.ref (store ref element) is an opcode, not a function. There's not much you can do to reduce it besides reducing the array-set instructions. Depending on the algorithm and use case that's probably not possible.