WP7 c# /XNA中的可变字符串

本文关键字:字符串 XNA WP7 | 更新日期: 2023-09-27 18:08:06

我正在制作一款Windows Phone 7 XNA游戏。这是一款用c++编写的游戏的移植版本,因此,我尽量少重写游戏玩法代码。

在WP7上,

垃圾是一个严重的问题,因为收集器是非分代的并且速度很慢,所以一个收集(每1MB触发一次)每MB分配大约需要10ms。我完全打算使用可用的最大90MB,所以我们看到的是每MB分配约900ms的延迟。

我已经能够重做一些事情,这样我们就不会每帧生成垃圾,除了少数情况下的字符串。

似乎StringBuilder.ToString()产生垃圾,这里描述的方法在WP7上不起作用。

我需要做的两件事是:

  • 分/秒/百分格式为mm:ss。Hh表示显示到屏幕上。显然,我可以做到这一点与StringBuilder(使用扩展方法,不创建垃圾从装箱的int),并显示StringBuilder直接与SpriteBatch。
  • 拆分形式为"foo.bar.baz "的字符串。将' '转换为' '的数组。',即{"foo", "bar", "baz", "qux"},并一次复制一个元素到字符串数组中。这是为了设置游戏角色的层次状态。它也是直接从最初的游戏中移植而来,并且很大程度上依赖于这种方式。我真的很想避免重写它。

没有转换大量的代码使用char[]而不是字符串,有没有办法在c#中拥有真正的无垃圾可变字符串?

WP7 c# /XNA中的可变字符串

为什么首先需要将StringBuilder转换为String ?正如您所注意到的,您可以将StringBuilder直接传递到XNA的绘图方法中。您也可以使用StringBuilder来检索子字符串:

substringBuilder.Length = 0;
for (int i = start; i <= end; i++)
    substringBuilder.Append(originalBuilder[i]);

StringBuilder唯一要避免的是ToString()AppendFormat()。其他格式化方法(据我所知)都不会产生垃圾。更新:我错了。编写自己的扩展方法。使用StringBuilder

时避免垃圾

编写基于给定分隔符将字符串拆分为子字符串的方法相对容易。请记住,String.Split()两个原因下是邪恶的——首先,因为它分配新的字符串;其次,因为它分配了一个新的数组。字符串的不变性只是问题的一半。

考虑以下StringBuilder的扩展方法。我还没有对这段代码进行彻底的测试,但它应该给您一个大致的概念。请注意,它希望您传入一个预分配的数组,然后它将填充该数组。

public static void Substring(this StringBuilder source, Int32 start, Int32 count, StringBuilder output)
{
    output.Length = 0;
    for (int i = start; i < start + count; i++)
    {
        output.Append(source[i]);
    }
}
public static int Split(this StringBuilder source, Char delimiter, StringBuilder[] output)
{
    var substringCount = 0;
    var substringStart = 0;
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == delimiter)
        {
            source.Substring(substringStart, i - substringStart, output[substringCount]);
            substringCount++;
            substringStart = i + 1;
        }
    }
    if (substringStart < source.Length - 1)
    {
        source.Substring(substringStart, source.Length - substringStart, output[substringCount]);
        substringCount++;
    }
    return substringCount;
}

我正在尽可能少地重写游戏代码。

小心,重写可能需要更长的时间。Cole Campbell是对的,当你想绘制它的时候调用ToString()是没有意义的。XNA的绘制方法使用StringBuldier,它在我的游戏中运行良好。

你的问题的另一个解决方案:为你的字符串创建一个全局HashSet,并在加载游戏或关卡时设置它,以避免收集压力。

加载游戏时尽量多做一些