WP7 C#/ XNA中的可变字符串?

jlo*_*eet 10 c# xna garbage-collection windows-phone-7

我正在开发一款Windows Phone 7 XNA游戏.它是用C++编写的游戏的端口,因此,我试图尽可能少地重写游戏代码.

垃圾是WP7上的一个问题,因为收集器是非代数且速度慢的,因此一个集合(每1MB触发一次)每MB分配大约需要10ms.我完全打算使用最大的90MB可用,所以我们正在考虑每MB分配约900ms的停顿.

我已经能够重做工作,因此我们没有每帧生成垃圾,除了一些字符串的情况.

似乎StringBuilder.ToString()生成垃圾,这里描述的方法不适用于WP7.

我需要做的两件事是:

  • 格式化分钟/秒/ hundreths为mm:ss.hh以显示在屏幕上.显然,我可以使用StringBuilder(使用不会因装箱而创建垃圾的扩展方法)并使用SpriteBatch直接显示StringBuilder.
  • 将"foo.bar.baz.qux"形式的字符串拆分为"."上的数组,即{"foo","bar","baz","qux"},并将一个元素一次复制到字符串数组.这用于设置游戏角色的层次状态.它也几乎直接从原始游戏移植过来,而且很大程度上依赖于它以这种方式工作.我真的想避免重写它.

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

Col*_*ell 10

为什么你需要首先将a转换StringBuilder为a String?如您所知,您可以StringBuilder直接进入XNA的绘图方法.您还可以使用StringBuilder检索子字符串:

substringBuilder.Length = 0;
for (int i = start; i <= end; i++)
    substringBuilder.Append(originalBuilder[i]);
Run Code Online (Sandbox Code Playgroud)

你想要避免的唯一的事情StringBuilderToString()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;
}
Run Code Online (Sandbox Code Playgroud)