Sto scrivendo un motore di particelle e ho notato che è molto più lento di quanto dovrebbe essere (ho scritto motori 3D C++ altamente non ottimizzati che possono rendere 50k particelle a 60 fps, questo scende a 32 fps intorno a 1,2 k ..), ho fatto alcune analisi sul codice ipotizzando il rendering delle particelle o le rotazioni erano l'operazione più intensiva della CPU, tuttavia ho scoperto che in realtà queste due piccole proprietà dell'oggetto grafico stanno effettivamente consumando più del 70% di la mia prestazione ....Graphics.Transform è estremamente inefficiente, cosa posso fare a riguardo?
public void RotateParticle(Graphics g, RectangleF r,
RectangleF rShadow, float angle,
Pen particleColor, Pen particleShadow)
{
//Create a matrix
Matrix m = new Matrix();
PointF shadowPoint = new PointF(rShadow.Left + (rShadow.Width/1),
rShadow.Top + (rShadow.Height/1));
PointF particlePoint = new PointF(r.Left + (r.Width/1),
r.Top + (r.Height/2));
//Angle of the shadow gets set to the angle of the particle,
//that way we can rotate them at the same rate
float shadowAngle = angle;
m.RotateAt(shadowAngle, shadowPoint);
g.Transform = m;
//rotate and draw the shadow of the Particle
g.DrawRectangle(particleShadow, rShadow.X, rShadow.Y, rShadow.Width, rShadow.Height);
//Reset the matrix for the next draw and dispose of the first matrix
//NOTE: Using one matrix for both the shadow and the partice causes one
//to rotate at half the speed of the other.
g.ResetTransform();
m.Dispose();
//Same stuff as before but for the actual particle
Matrix m2 = new Matrix();
m2.RotateAt(angle, particlePoint);
//Set the current draw location to the rotated matrix point
//and draw the Particle
g.Transform = m2;
g.DrawRectangle(particleColor, r.X, r.Y, r.Width, r.Height);
m2.Dispose();
}
Cosa sta uccidendo il mio rendimento è specificamente queste righe:
g.Transform = m;
g.Transform = m2;
Un po 'di background, l'oggetto grafico viene catturato da painteventargs, quindi esegue il rendering di particelle sullo schermo in un metodo di rendering delle particelle, che chiama questo metodo per eseguire qualsiasi rotazione, il multi-threading non è una soluzione come l'oggetto grafico non può essere condiviso tra più thread. Ecco un link per l'analisi del codice mi sono imbattuto solo così si può vedere cosa sta succedendo così:
https://gyazo.com/229cfad93b5b0e95891eccfbfd056020
sto po 'pensando che questo è qualcosa che non può davvero essere aiutato perché sembra che la proprietà stesso sta distruggendo le prestazioni e non tutto quello che ho effettivamente fatto (anche se sono sicuro che ci sono margini di miglioramento), specialmente dal momento che la DLL che la classe chiama utilizza la maggior parte della potenza della CPU. Ad ogni modo, qualsiasi aiuto sarebbe molto apprezzato nel tentativo di ottimizzare questo ... forse mi limiterò a abilitare/disabilitare la rotazione per aumentare le prestazioni, vedremo ...
Anche io mi scuso per l'immagine, so che è veramente piccola, se si strizza l'occhio si possono vedere i numeri però! : P –