Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WP7 C#/XNA中的可变字符串?_C#_Windows Phone 7_Garbage Collection_Xna - Fatal编程技术网

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

WP7 C#/XNA中的可变字符串?,c#,windows-phone-7,garbage-collection,xna,C#,Windows Phone 7,Garbage Collection,Xna,我正在开发一款WindowsPhone7XNA游戏。它是C++编写的游戏的一个端口,因此,我尽量尽可能少地重写游戏代码。 垃圾在WP7上是一个巨大的问题,因为收集器是非代的且速度慢,所以每MB分配一次收集(每1MB触发一次)大约需要10ms。我完全打算使用最多90MB的可用空间,因此我们希望每分配一MB就有900ms的暂停时间 我已经能够修改一些东西,这样我们就不会在每帧中生成垃圾,除了一些字符串的情况 似乎StringBuilder.ToString()会生成垃圾,并且所描述的方法在WP7上不

我正在开发一款WindowsPhone7XNA游戏。它是C++编写的游戏的一个端口,因此,我尽量尽可能少地重写游戏代码。 垃圾在WP7上是一个巨大的问题,因为收集器是非代的且速度慢,所以每MB分配一次收集(每1MB触发一次)大约需要10ms。我完全打算使用最多90MB的可用空间,因此我们希望每分配一MB就有900ms的暂停时间

我已经能够修改一些东西,这样我们就不会在每帧中生成垃圾,除了一些字符串的情况

似乎StringBuilder.ToString()会生成垃圾,并且所描述的方法在WP7上不起作用

我需要做的两件事是:

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

除了将大量代码转换为使用char[]而不是string之外,有没有办法在C#中使用真正无垃圾的可变字符串?

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

substringBuilder.Length = 0;
for (int i = start; i <= end; i++)
    substringBuilder.Append(originalBuilder[i]);
我正在尽可能少地重写游戏代码

注意,重写可能需要更长的时间。Cole Campbell是对的,当您想要绘制ToString()时调用它是没有意义的。XNA有一种抽签的方法,它需要更多的球员,在我的比赛中效果很好

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


加载游戏时,尽量多做些事情。

芒果有一个附带说明,它有分代GC。这也是一种使某些东西“更接近”可变字符串的方法。格式化非字符串对象(例如:数字)将生成垃圾(它调用它们的
ToString
方法)。但是,编写一个无垃圾的扩展方法来附加整数(实际上是大多数其他类型的整数)是非常简单的。你可以很容易地在网上找到例子。快速浏览反编译的源代码可以确认你是正确的。我不知道为什么我不这么想。但是是的,你可以解决这个问题。
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;
}