Lag spikes on trivial code, and profiler data that makes no sense

Our game is running really smoothly except on a few frames that take 300% of the usual time, and even worse on the iPhone(our target), causing a visible lag.

The strange thing is that the profiler says that the lag comes from completely trivial methods that usually execute in an instant. (like taking several ms for removing an element from a very small list…) It looks like the lags come the first time those key methods are invoked.

This strange behaviour is consistant and the results and graph shown below can be easily be reproduced.

Here is an example of the code that supposedly takes 50% of a very slow frame …

public class MediumEnemy : Enemy {
	override public void Die(){							// 50% of frame time, self 5.8%
		game.SpawnBonusUpgrade(posForward,posLateral);	// 12%
		base.Die();									// 30%
	}
}
public class Enemy : PathEntity{
	override public void RemoveFromScene(){				// 27%, self 5.8%
		game.GetEnemies().Remove((Enemy)this);			// 19.2%
		base.RemoveFromScene();
	}
}
public class PathEntity : MonoBehaviour{
	Game game;						
	float posForward,posLateral;
	GameObject pathFollower;							// an empty game object
	virtual public void Die(){							// 30% of frame time, self 2.8%
		if(diePrefab != null){
			GameObject explosion =  (GameObject)Instantiate(diePrefab,transform.position, transform.rotation);	//1.2%
			if(diePrefabDuration > 0.0f){
				Destroy(explosion,diePrefabDuration);				//0.1%
			}
		}		
		Destroy(this.gameObject,0.0f);							 // 0.1%
		RemoveFromScene();		//Calls Enemy.RemoveFromScene()  // 27.0%
	}
	virtual public void RemoveFromScene(){						 //1.9%
		Destroy(pathFollower.gameObject);
		Destroy(this.gameObject);
	}
}
public class Game : MonoBehaviour {
	List<Enemy> gameEnemies;								//never more than 10 elements
	public List<Enemy> GetEnemies(){
		return gameEnemies;
	}
}

Afterwards, the same code executes nearly instantly (as expected)

Here is a capture of Unity showing the data above
http://www.mentalwarp.com/~g0/lag_01.png

Any ideas ?

Looks like all your slowdown is coming from removing an entity from the List<> class. Lists are essentially wrapped arrays, so some operations on them can be relatively slow.

In this case, Remove searches through every element of the array, finds your match, then removes it, then (possibly?) rebuilds the array. So this can be especially long if you have a lot of enemies, or the array elements need to be shifted (I’m still not sure if it does this or not; the MSDN doesn’t mention it, but I suspect it would)

If you want it to have a quick removal, try using a Dictionary<,> and give your enemies a unique ID to use as the lookup key (I think you can use the enemies themselves as the lookup key, it’ll just use their object hash just fine)

EDIT: after rereading, the lookup itself my not be the slowdown but the rebuilding. How many items to you put in there? If that’s the case that it’s the rebuild, not the slowdown, maybe you’ll need to use a LinkedList instead.

This one definitely would favor linkedlist, cause the O(1) removal from the linked list as well as reordering on O(1) base is totally unbeatable for a list with the requirements of the one here

At the execution of this code, there is 5 elements in the list. It should not take much time, certainly not 0.7ms. Also, later in the game, the same code executes for larger list in much less time. It only takes this much time the first time it is executed. I get the same behaviour with several other methods; the first time they are called, they lag a lot.

I suspect that it might be a problem with the JIT compilation…

If that’s the case fvdsn, then that sucks, but a possibility. (though, I thought the JIT compilation happens as types are loaded, so everything should be good to go anyway… but I don’t know what Unity/Mono is doing in the back-end)

Try creating an initialization step before your game “starts” that simply creates a garbage List and calls Add/Remove on it; take the overhead at the game start.