[英]Mutable strings in WP7 C#/XNA?
I'm working on a Windows Phone 7 XNA game. 我正在开发一款Windows Phone 7 XNA游戏。 It's a port of a game written in C++, and as such, I'm trying to do as little rewriting of gameplay code as possible.
它是用C ++编写的游戏的端口,因此,我试图尽可能少地重写游戏代码。
Garbage is a huge problem on WP7, because the collector is nongenerational and slow, so a collection (which is triggered every 1MB) takes about 10ms per MB of allocations. 垃圾是WP7上的一个大问题,因为收集器是非代数且速度慢的,因此一个集合(每1MB触发一次)每MB分配大约需要10ms。 I fully intend to be using the maximum 90MB available, so we're looking at a ~900ms stall every MB of allocation.
我完全打算使用最大可用的90MB,因此我们正在考虑每MB分配约900ms的停顿时间。
I've been able to rework things so that we don't have garbage generated per-frame, except for a few cases of strings. 我已经能够重做工作,因此我们没有每帧生成垃圾,除了一些字符串的情况。
It seems that StringBuilder.ToString() generates garbage, and the method described here doesn't work on WP7. 似乎StringBuilder.ToString()生成垃圾, 这里描述的方法不适用于WP7。
The two things I need to do are: 我需要做的两件事是:
Short of converting a lot of code to use char[] instead of string, is there any way to have truly garbage-free mutable strings in C#? 如果没有将大量代码转换为使用char []而不是字符串,那么有没有办法在C#中拥有真正无垃圾的可变字符串?
Why do you need to convert a StringBuilder
to a String
in the first place? 为什么首先需要将
StringBuilder
转换为String
? As you've noted, you can pass StringBuilder
directly into XNA's drawing methods. 如您所知,您可以将
StringBuilder
直接传递给XNA的绘图方法。 You can also use StringBuilder
to retrieve substrings: 您还可以使用
StringBuilder
来检索子字符串:
substringBuilder.Length = 0;
for (int i = start; i <= end; i++)
substringBuilder.Append(originalBuilder[i]);
The only things you want to avoid with
StringBuilder
are
ToString()
and
AppendFormat()
.
StringBuilder
唯一要避免的是
ToString()
和
AppendFormat()
。
None of the other formatting methods (to my knowledge) generate garbage.
没有其他格式化方法(据我所知)生成垃圾。
Update: I was wrong. 更新:我错了。 Write your own extension methods.
编写自己的扩展方法。 A rundown is available here: Avoiding garbage when working with StringBuilder
这里提供了一个简介: 使用StringBuilder时避免垃圾
It's relatively easy to write a method that will split a string into substrings based on a given delimiter. 编写一个方法会相对容易,该方法会根据给定的分隔符将字符串拆分为子字符串。 Just remember that
String.Split()
is evil for two reasons -- first, because it allocates new strings; 请记住
String.Split()
是邪恶的,原因有二 :首先,因为它分配了新的字符串; and second, because it allocates a new array . 第二,因为它分配了一个新数组 。 The immutability of strings is only half of your problem.
字符串的不变性只是你问题的一半。
Consider the following extension methods for StringBuilder
. 请考虑
StringBuilder
的以下扩展方法。 I haven't thoroughly tested this code, but it should give you a general idea. 我还没有彻底测试过这段代码,但它应该给你一个大致的想法。 Note that it expects you to pass in a pre-allocated array, which it will then populate.
请注意,它希望您传入一个预先分配的数组,然后填充该数组。
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;
}
I'm trying to do as little rewriting of gameplay code as possible.
我试图尽可能少地重写游戏代码。
Careful with that it may take longer that rewrite. 小心,重写可能需要更长时间。 Cole Campbell is right, there is no point in calling ToString() while you want to draw it.
Cole Campbell是对的,在你想要绘制ToString()时没有任何意义。 XNA has draw method that takes StringBuldier and it works well in my game.
XNA有draw方法,它采用StringBuldier,在我的游戏中运行良好。
Another solution to your problem: make a global HashSet of your strings and set up it when you load the game or level to avoid collection pressure. 问题的另一个解决方案:创建字符串的全局HashSet并在加载游戏或级别时设置它以避免收集压力。
Try to do as much as possible when you load the game. 加载游戏时尽可能多地尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.