我有一个每次更新被调用数十万次的函数,我需要优化它。现在,我通常遵循“不要太快优化”的规则,但这是一个关键功能,几乎所有代码的时间都用在了,所以你能提出的任何建议都会有所帮助。我也不熟悉可用于优化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;
答案 0 :(得分:2)
我要尝试的第一件事就是丢失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++)
也;什么是PositionData
? struct
或class
?我很想尝试这两种方法 - 确保它是不可变的,并通过构造函数传递数据以使IL更瘦:
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()获得。
答案 1 :(得分:2)
首先,尝试使用一维数组而不是_restPositions
的矩形数组 - CLR针对基于零的一维数组进行了优化。只需在数组中保留一个索引,并在每次迭代时递增它:
int index = 0;
// I'm assuming you can pass in width and height separately
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
PositionData temp = new PositionData
{
indexX = x,
indexY = y,
value = _restPositions[index],
distance = (linearPosition - _restPositions[index]).Length()
};
if (temp.distance < fourNearestPoints[0].distance)
{
fourNearestPoints[3] = fourNearestPoints[2];
fourNearestPoints[2] = fourNearestPoints[1];
fourNearestPoints[1] = fourNearestPoints[0];
fourNearestPoints[0] = temp;
}
index++;
}
}
如果您可以使PositionData
的构造函数采用适当的值而不是具有单独的属性设置器,则可能也可以帮助。
您还要多次索引到fourNearestPoints
- 任何不使用四个局部变量的原因?它不会做太多,但你永远不会知道......