c# - 优化 XNA 中的高流量函数

标签 c# .net optimization xna

我有一个每次更新都会调用数十万次的函数,我需要对其进行优化。现在,我通常遵循“不要过早优化”的规则,但这是一个关键功能,几乎我所有的代码时间都花在了这个功能上,所以你能提出的任何建议都会有所帮助。我也不熟悉可用于优化 XNA 或 c# 代码的任何类型的提示和技巧。你能帮帮我吗?

if (linearPosition.Y < _min.Y || linearPosition.Y > _max.Y)// the nonlinear space commisioned doesn't cover it so that's the behavior i want, same case with next line
{
    return linearPosition;
}
if (linearPosition.X < _min.X || linearPosition.X > _max.X)
{
    return linearPosition;
}
PositionData[] fourNearestPoints = new PositionData[4] 
{
    new PositionData {distance = float.MaxValue},
    new PositionData {distance = float.MaxValue},
    new PositionData {distance = float.MaxValue},
    new PositionData {distance = float.MaxValue}
};

for (int x = 0; x < _restPositions.GetLength(0); x++)
{
    for (int y = 0; y < _restPositions.GetLength(1); y++)
    {
        PositionData temp = new PositionData
        {
            indexX = x,
            indexY = y,
            value = _restPositions[x,y],
            distance = (linearPosition - _restPositions[x,y]).Length()
        };
        if (temp.distance < fourNearestPoints[0].distance)
        {
            fourNearestPoints[3] = fourNearestPoints[2];
            fourNearestPoints[2] = fourNearestPoints[1];
            fourNearestPoints[1] = fourNearestPoints[0];
            fourNearestPoints[0] = temp;
        }
    }
}
Vector2 averageRestVector = new Vector2((fourNearestPoints[0].value.X +
    fourNearestPoints[1].value.X +
    fourNearestPoints[2].value.X +
    fourNearestPoints[3].value.X) / 4,
    (fourNearestPoints[0].value.Y +
    fourNearestPoints[1].value.Y +
    fourNearestPoints[2].value.Y +
    fourNearestPoints[3].value.Y) / 4);
Vector2 averageDeformedVector = new Vector2((_deformedPositions[fourNearestPoints[0].indexX, fourNearestPoints[0].indexY].X +
    _deformedPositions[fourNearestPoints[1].indexX, fourNearestPoints[1].indexY].X +
    _deformedPositions[fourNearestPoints[2].indexX, fourNearestPoints[2].indexY].X +
    _deformedPositions[fourNearestPoints[3].indexX, fourNearestPoints[3].indexY].X) / 4,
    (_deformedPositions[fourNearestPoints[0].indexX, fourNearestPoints[0].indexY].Y +
    _deformedPositions[fourNearestPoints[1].indexX, fourNearestPoints[1].indexY].Y +
    _deformedPositions[fourNearestPoints[2].indexX, fourNearestPoints[2].indexY].Y +
    _deformedPositions[fourNearestPoints[3].indexX, fourNearestPoints[3].indexY].Y) / 4);

Vector2 displacement = averageDeformedVector - averageRestVector;
return linearPosition + displacement;

最佳答案

我要尝试的第一件事是丢失 fourNearestPoints 数组...也许只对 4 个最近的位置使用 4 个变量。你总是通过常量索引来处理它,所以这应该是一个简单的改变,特别是如果你像数组索引一样命名:

PositionData fourNearestPoints_0 = ...,
             fourNearestPoints_1 = ...,
             fourNearestPoints_2 = ...,
             fourNearestPoints_3 = ...;

接下来我要看的是 _restPositions 的用法;我不知道 GetLength(在此使用中)是否会被优化,所以我会尝试预先缓存它。在线性数组中,.Length 被优化(至少在完整的 CLR 中)- 但不是 GetLength AFAIK:

int width = _restPositions.GetLength(0), height = _restPositions.GetLength(1);
for (int x = 0; x < width; x++)
{
    for (int y = 0; y < height; y++)

还有;什么是 PositionDatastruct 还是 class?我很想尝试这两者——确保它是不可变的,并通过构造函数传递数据以使 IL 更 slim :

PositionData temp = new PositionData(x, y, _restPositions[x,y],
        (linearPosition - _restPositions[x,y]).Length());

在下面,你正在做一些大部分时间被丢弃的工作:

    PositionData temp = new PositionData
    {
        indexX = x,
        indexY = y,
        value = _restPositions[x,y],
        distance = (linearPosition - _restPositions[x,y]).Length()
    };
    if (temp.distance < fourNearestPoints[0].distance)
    {
        fourNearestPoints[3] = fourNearestPoints[2];
        fourNearestPoints[2] = fourNearestPoints[1];
        fourNearestPoints[1] = fourNearestPoints[0];
        fourNearestPoints[0] = temp;
    }

我会这样做:

var distance = (linearPosition - _restPositions[x,y]).Length();
if (distance < fourNearestPoints_0.distance) {
    fourNearestPoints_3 = fourNearestPoints_2;
    fourNearestPoints_2 = fourNearestPoints_1;
    fourNearestPoints_1 = fourNearestPoints_0;
    fourNearestPoints_0 = new PositionData(x, y, _restPositions[x,y], distance);
}

我也对 distance=... 行感兴趣;有很多我们看不到的地方可能需要更多的工作——- 运算符和 Length() 方法。


我假设 Length() 涉及平方根是否正确? (昂贵)您可以通过以平方距离工作来避免这种情况。您可能需要使用不求根的平方长度方法来明确这一点,并在整个过程中比较平方长度,但您可以节省大量 CPU 周期。这可用作 LengthSquared() .

关于c# - 优化 XNA 中的高流量函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1654041/

相关文章:

c# - 在 WPF 中显示 RichTextBox 中的行号

c# - Linq 返回实体中的所有记录,其中字段包含列表中的一个或多个单词

c# - 如何在 c# 中单击按钮时显示 iframe,并在显示另一个网格或 iframe 时使其不可见?

c# - 基于 Session 值的 MVC OutputCache

javascript - 优化在数组中搜索匹配项的 JavaScript 代码

c# - 反序列化具有未知值名称的 JSON 并在 C# 中获取所述名称

.net - 使用 Bootstrap 在 Telerik 中编辑按钮样式

c# - 在我的.net程序运行时仍要处理奇怪的错误吗?

ios - SpriteKit 游戏中的帧速率极慢

javascript - 解决在 Chrome 中使用 jQuery 实时过滤 1500 多个项目的问题