在指定范围内获得所有积分的最快方法

时间:2019-06-12 03:41:49

标签: c#

我试图找出最快的方法来检索二维数组中某个范围内给定坐标周围的所有点/坐标。

我当前正在遍历X / Y,并将所有点添加到列表中,但是当范围开始增加时,它却变得非常慢。 除了我目前的工作方式,还有其他方法可以更有效地实现这一目标吗?

我当前的代码:

public static List<coords> GetCoordinates(coords Position, int nRange)
    {
        List<coords> inRange = new List<coords>();
        for (int i = Position.X - nRange; i <= Position.X + nRange; i++)
            for (int j = Position.Y - nRange; j <= Position.Y + nRange; j++)
                inRange.Add(new coords() { X = i, Y = j });
        return inRange;
    }

2 个答案:

答案 0 :(得分:1)

第一步: Capitalize your variables correctly。通过pascal封装类和骆驼封装参数,您将获得50%的速度提升:

public static List<Coords> GetCoordinates(Coords position, int range)

好的,我对执行速度的提高撒谎,但是可读性的提高是真实的。 ?

第二步:确保Coordsstruct,以消除垃圾收集器的压力:

public struct Coords { public int X; public int Y; }

第三步:预分配List<Coords>所需的空间,以避免对内部数组进行多次调整。

var inRange = new List<Coords>((range * 2 + 1) ^ 2);

或者不预先分配任何内容,而是返回迭代器而不是列表:

public static IEnumerable<Coords> GetCoordinates(Coords position, int range)
{
    for (int i = position.X - range; i <= position.X + range; i++)
        for (int j = position.Y - range; j <= position.Y + range; j++)
            yield return new Coords() { X = i, Y = j };
}

另一种方法是返回满足条件的随机Coords

public static Random _random = new Random();
public static Coords GetRandomCoordinates(Coords position, int range,
    Func<Coords, bool> condition)
{
    while (true)
    {
        var coords = new Coords()
        {
            X = _random.Next(position.X - range, position.X + range + 1),
            Y = _random.Next(position.Y - range, position.Y + range + 1)
        };
        if (condition(coords)) return coords;
    }
}

...并像这样使用它:

var result = GetRandomCoordinates(position, range,
    (coords) => !players.Any(player => player.X == coords.X && player.Y == coords.Y));

答案 1 :(得分:0)

如果您已经知道总大小,则使用固定数组会更快

int width = nRange + nRange + 1;
coords[] inRange = new coords[width * width];

并缓存for循环的结束值

int endX = Position.X + nRange;
int endY = Position.Y + nRange;
for (int i = Position.X - nRange; i <= endX; i++)
     for (int j = Position.Y - nRange; j <= endY; j++)

基准

坐标是一流的

 nRange          |           1000               |           5000            
-----------------+------------------------------+---------------------------
 Method          |   List           Array       | List          Array       
-----------------+------------------------------+---------------------------
 AVG(ms)         |   312.90858      254.00218   | 8201.48866    7634.8847   
 MAX             |   321.8542       259.0914    | 8498.696      7914.6034   
 MIN             |   300.2323       248.8317    | 7908.7473     7529.3754   
 STDEV           |   9.564255412    3.654335875 | 220.2477895   159.5085045 

coords是struct

 nRange          |            1000              |           5000               
-----------------+------------------------------+------------------------------
 Method          |   List           Array       |  List            Array       
-----------------+------------------------------+------------------------------
 AVG(ms)         |   56.68224       14.2345     |  1454.1773       296.05854   
 MAX             |   57.3408        15.4369     |  1472.1977       298.0693    
 MIN             |   56.2184        12.752      |  1444.9573       293.7728    
 STDEV           |   0.468124121    1.081463106 |  10.57876523     1.925248377