   Particle System optimization in XNA
  I have created a particle system in 2D and I was wondering if anyone knew any tricks for optimization in a particle system. Right now it can do about 3000 particles with no noticeable performance hit on a laptop with 4 gig ram,2.0 processor with a generic graphics card. I would like this to be 5000+ so I can create more realistic effectsI have made it so it is very customizable with custom particle updating and a way to change the particles update options such as wind, chaos, gravity, and other forces.All I could think of to optimize this is to put some of the calculations onto the gpu instead of the cpu, but I do not know how to do this. Any other tips/tricks you can think of would be very helpful.here is my Update logicanything with D at the end is a dictionary, so you can all together ingore that. The particleArray holds all the actual particles, and the particleList holds the index of all the active particles in the particleArray.I've added a lot of comments so people can understand it better.public void Update(GameTime gameTime) {  //delete old particles  int i = 0;//put outside to insure no outofrange exceptions and correct deleting  loop1://the loop to goto after removal to restart the loop  for(; i < particleList.Count; i++) { if(!particleArray[particleList].Alive) {particleList.RemoveAt(i);goto loop1; }  }  //create new particles  foreach(short psos in currentPSOs) {//psos is the PartleSystemOptions which holds the wind,gravity,chaos ect. its short because it    //will be refrenced in the dictionary PSOsD float newParticles = PSOsD[psos].leftOver + (PSOsD[psos].ParticlesPerSecond * (float)gameTime.ElapsedGameTime.TotalSeconds); //use the existing iterator since it is there for(i = 0; i < particleArray.Length; i++) {if(newParticles >= 1) {    if(!particleArray.Alive) {   particleArray = new Particle(  PSOsD[psos].ParticleShell,//contains the textureID,particleWidth,particleHeight,and the tint color  new Vector2(//start position is a random position inside the emitter Randomizer.GetRand(emitterPos.X,emitterPos.X + emitterWidth), Randomizer.GetRand(emitterPos.Y,emitterPos.Y + emitterHeight)  ),  PSOsD[psos].Speed.GetRand() * PSOsD[psos].DirectionVector,//the velocity  PSOsD[psos].Age.Min,//the starting age  PSOsD[psos].Age.Max,//the max age  PSOsD[psos].Rotation.GetRand(),  PSOsD[psos].RotationalVelocity.GetRand()   );   newParticles -= 1;   particleList.Add(i);    }}else {    PSOsD[psos].leftOver = newParticles;    break;} }  }  //update alive particles  foreach(int p in particleList) {//go threw each alive particle particleArray.Update(//updates the particlePSOsD[particleArray.particleShell.psosID].GetForces(//gets the forces from the PSOS it is associated with    (float)gameTime.ElapsedGameTime.TotalSeconds,particleArray.velocity),    (float)gameTime.ElapsedGameTime.TotalSeconds); //changes the changePos(or the associated ParticleShell) of the particle if(ChangeParticle != null) {foreach(ParticleChange EVENT in ChangeParticle.GetInvocationList())    if(particleArray.changePos - 1 < changeOrder.Count - 1)   if(ChangeParticle(particleArray)) {  particleArray.changePos++;  particleArray.particleShell = particleD[changeOrder[particleArray.changePos - 1]];   } } //custom updating if(UpdateParticle != null) {foreach(ParticleUpdate EVENT in UpdateParticle.GetInvocationList())    EVENT(ref particleArray); }   }   }anything you guys see that will increase preformace please say something, or any other errors you may spot Id like to know about.   
  I haven't looked at it in detail, but the particle removal code is inefficient. Each call to RemoveAt(i) needs to shift all the elements after i to the left, so there's a lot of copying.There's another method that does this and is much more efficient (RemoveAll), but I think using it here is problematic because of how the indices are used.You can try looking at some of the articles in the Articles section on this site, there are a few that deal with particle systems. This article also seems useful. They might give you some ideas for a better way to structure your code.You should also look at the particle sample for XNA.   ;  For particles, especially short-lived transient ones, you are not going to want to create/destroy them. For max performance you will want to re-use the particle memory. There are a few ways to do it, but the simplest is to mark each particle with an "active" flag and simply ignore inactive particles during update/draw.A while back there was a thread in here where someone implemented a particle system in a few different ways. IIRC allocating/deallocating particle memory caused about a 50% performance hit for many particles compared to fixed allocation. I'll try to find it.edit: Here it is and it is actually on C# particle systems too:http://www.gamedev.net/community/forums/topic.asp?topic_id=532672   ;  Ty for the awesome post link, exactly what I needed. My particle system implements #3 in the first post of that. This is because I only allocate - de-allocate the index of the particle in a fixed sized array. Long post so I still have a lot of 'studying' to do.   