Случайное снижение производительности в wp7 xna? - PullRequest
2 голосов
/ 14 мая 2011

Я работаю над своей первой игрой для Windows Phone 7 с xna.После некоторого тестирования я заметил короткие замедления в игровой анимации и реализовал некоторые тесты производительности, но не смог полностью удалить замедления.Теперь я создал пустой проект, в котором только унаследованный класс DrawableGameComponent рисует текст о флаге runsslow, времени Draw / Update (передается в методы) и, если сборщик мусора работал.Странно то, что даже при использовании этого минималистичного кода задержки появляются примерно раз в 1–5 секунд.С задержкой я обращаюсь к случаю, когда рисунок занимает вместо 33 миллисекунд> 50 миллисекунд.Иногда даже флаг runsslow устанавливается в этом минималистичном проекте.Из моих экспериментов сборщик мусора, кажется, не главная причина этого, поскольку он выполняет намного меньше.Handy также установлен в режим полета, поэтому нет связи.

Код обновления:

    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;
        }
    }

Код розыгрыша:

    //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);
    }

Что я заметил,что это не происходит все время.

1 Ответ

2 голосов
/ 09 июня 2011

Это может помочь (http://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/) даже при использовании StringBuilder сборщик мусора все еще может быть неисправен.Ссылка выше объясняет, что некоторые из вызовов Append определенно генерируют мусор.У него также есть класс, который помогает генерировать меньше мусора с помощью метода stringBuilder.

Кроме того (http://devblog.andyc.org/2011/05/garbage-control/) использует сборщик мусора в строителе строк.

Вы пробовали использоватьCLR Profiler, чтобы увидеть, не возникает ли увеличение нагрузки на память?

...