Random performance breakdown in wp7 xna?
I'm working on my first game for Windows Pho开发者_运维知识库ne 7 with xna. After some testing I noticed short slow downs in the game animations and implemented some performance tests but wasn't able to remove the slow downs completely. Now I have created an empty project in which only a DrawableGameComponent inherited class draws text about the runsslow flag, the Draw/Update time (gets passed to the methods) and if the garbage collector was running. Strange is that even with this minimalistic code the delays seem to occure around once every 1 to 5 second. With a delay I'm refering to when a drawing takes instead of 33 millisconds >50 milliseconds. Sometimes even the runsslow flag is set in this minimalistic project. From my experiments the garbage collector seems to be not the main reason for this as he executes far less. The handy is also set to flight mode so no communication.
The update code:
public override void Update(GameTime gameTime)
{
elapsedTime += gameTime.ElapsedGameTime;
timeSpanUpdate.Add(gameTime.ElapsedGameTime.TotalMilliseconds);
if (elapsedTime.TotalMilliseconds >= timeToElapseForVisualisation)
{
//update the values messured
elapsedTime -= TimeSpan.FromMilliseconds(timeToElapseForVisualisation);
//get the values we are interested in
double sum = 0;
maxUpdateTime = int.MinValue;
foreach (double val in timeSpanUpdate)
{
sum += val;
maxUpdateTime = (int)Math.Max(maxUpdateTime, val);
}
averageUpdateTime = (int)(sum / timeSpanUpdate.Count);
timeSpanUpdate.Clear();
sum = 0;
maxDrawTime = int.MinValue;
foreach (double val in timeSpanDraw)
{
sum += val;
maxDrawTime = (int)Math.Max(maxDrawTime, val);
}
averageDrawTime = (int)(sum / timeSpanDraw.Count);
timeSpanDraw.Clear();
}
if (gameTime.IsRunningSlowly)
{
runsSlow = true;
timeToShowRunsslowRemaining = timeToShow;
}
else if (timeToShowRunsslowRemaining > 0)
{
timeToShowRunsslowRemaining -= gameTime.ElapsedGameTime.TotalMilliseconds;
}
else
{
runsSlow = false;
}
}
The draw code:
//we use stringbuilders as strings passed to drawstring can induce the gc
private StringBuilder drawText = new StringBuilder("Draw max: ");
private StringBuilder updateText = new StringBuilder("Update max: ");
private StringBuilder runsslowYes = new StringBuilder("runsslow: yes");
private StringBuilder runsslowNo = new StringBuilder("runsslow: no");
public override void Draw(GameTime gameTime)
{
DateTime now = DateTime.Now;
timeSpanDraw.Add((now - lastDrawCall).TotalMilliseconds);
lastDrawCall = now;
drawText.Remove("Draw max: ".Length, drawText.Length - "Draw max: ".Length);
drawText.Append(maxDrawTime);
updateText.Remove("Update max: ".Length, updateText.Length - "Update max: ".Length);
updateText.Append(maxUpdateTime);
spriteBatch.Begin();
if (maxDrawTime >= thresholdMaxDelays)
{
spriteBatch.DrawString(spriteFont, drawText, drawTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, drawText, drawTextPos, Color.White);
}
if (maxUpdateTime >= thresholdMaxDelays)
{
spriteBatch.DrawString(spriteFont, updateText, updateTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, updateText, updateTextPos, Color.White);
}
if (runsSlow)
{
spriteBatch.DrawString(spriteFont, runsslowYes, runsslowTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, runsslowNo, runsslowTextPos, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
What I have noticed also is that it doesn't occure all the time.
This might help ( http://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/ ) even using StringBuilder the garbage collector can still be at fault. The link above explains that some of the Append calls definetly generate garbage. It also has a class that helps to generate less garbage with stringBuilder Appends.
In addition ( http://devblog.andyc.org/2011/05/garbage-control/ ) uses a no garbage wrapper on string builder.
Have you tried using CLR Profiler to see if there is memory pressure building?
精彩评论