我正在开发一款游戏,而且正处于一个AI数字运算中间,我想尽可能地优化代码。我在我的代码中有几个结构,如Circle,Vector等。我希望通过此代码将GC的负载降至最低,因为它将每秒运行多次,并且在每次调用时将生成几个大型数组,执行大量计算。
我的问题是,如果我有一个可以“返回”多个值类型的小方法(即圆和向量的交集等),那么将其结果传回主方法的最高效方法是什么?
我可以想到几种方法:
什么是避免GC必须收集的堆上许多小的不必要的对象/数组的最佳策略?
答案 0 :(得分:7)
如果您遇到以下情况:
...然后你可能能够通过重复传入相同的数组(或List<T>
)并修改它来提高性能。另一方面,在进行任何更改之前,您应该绝对测量的性能。你还应该确定将会是什么&#34;足够好&#34;因此,您不必将代码从最自然的设计中折弯出去,而不是必须。
答案 1 :(得分:2)
这取决于您传递的数据类型,大多数时候游戏都使用了向量,交集数据等结构......
当数据是结构时,你应该避免List<T>
并传递每个值,因为数据被复制了。但这在很大程度上依赖于代码,有时候每个值传递可能会更快,有时则不会。我会做一些性能测试。您可以在没有分析器的情况下将此方法用于简单测试:
public static Int64 MeasureTime(Action myAction)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
myAction();
stopWatch.Stop();
return stopWatch.ElapsedMilliseconds;
}
在处理结构时,使用out
或ref
可能总是一种好方法。
所有这些情况都可能不会导致性能问题,它们只是解释我在使用结构时学到的最佳实践。要确定ref
和out
在每种情况下是否有用,都应进行性能测试。
ref
用于避免此类情况:
Vector input = new Vector(x, y, z);
input = ModifyVector(input); // This line causes copies of the input vector and it's slow
这里的性能取决于Vector
类的大小,每次使用以下方法都不是一个好习惯。返回一个简单的Int32时,它不是必需的,不应该用来保持代码的可读性。
正确的方式:
Vector input = new Vector(x, y, z);
ModifyVector(ref input);
当然ref
关键字可以用来使方法更快,什么都不返回,但是这种方法必须注意传递给它们的数据,并且应该避免修改它们。在某些情况下,速度优势可能超过50%(我有一个高性能的矢量库,我测试了很多情况)。
out
用于避免此类情况:
Ray ray = ...;
CollisionData data = CastRay(ref ray); // Note the ref here to pass the Ray which contains 6 floats
CollisionData至少包含它撞击地面的点和法线。在这里使用out
来获得结果时,它应该更快。
正确的方式:
Ray ray = ...;
CollisionData data;
CastRay(ref ray, out data);
使用数组时..
..您应该知道数组已经是一个引用,并且您不需要ref
或out
关键字来处理它们。但是在使用结构时,您应该知道您没有保存数组中结构的引用。因此,当修改数组的值时,您可以使用ref myArray[0]
将值传递给方法,并在索引零处修改结构而不复制它。还要避免创建它们的新实例。
答案 2 :(得分:0)
不知道你的平台/框架是什么(XNA?),但我在Windows Phone 7下遇到了GC的问题(7.5有代际GC,但没有测试过)。为了避免所谓的GC冻结,我制作了一个集合,我将所有必要的数据预先加载到Dictionary中。
但首先是衡量措施措施。