【问题标题】:Better algorithm for searching through an array of points?搜索点数组的更好算法?
【发布时间】:2021-04-29 10:04:54
【问题描述】:

我有一个结构数组,其中每个结构都是一个 2D 位置(一对 32 位值)。该数组用于跟踪地图上的兴趣点。

struct Point {
    int x;
    int y;
};

// ...

struct Point pointsOfInterest[1024];

问题是,这些兴趣点在不断变化,这意味着数组中的条目被非常频繁地添加或删除。最重要的是,每个报告的兴趣点可能已经存在于数组中,所以我不能盲目地添加新的而不检查它们是否已经存在。

此时数组未排序(新条目添加到末尾,交换和弹出删除),我遍历整个列表以查找要删除或重复检查的条目。我想知道加快这个过程的选项是什么。

  • 在其他语言中,这是我分解字典或哈希集的地方。 C 中都不存在,所以我必须权衡添加类似内容的复杂性。
  • 我考虑过对列表进行排序(即先按 X,然后按 Y)。但是考虑到更新的频率,我觉得我会比迭代时更频繁地敲击表格。但我对排序算法的了解很少。
  • 在这里使用某种二叉树会更好吗?还是我会再次花费所有时间重新平衡树?
  • 理论上,考虑到这些算法的(感知)复杂性,是否存在一个阈值,低于该阈值线性搜索仍然是可行的选择?

我假设这是一个已知已解决的问题,所以我希望在我花大量时间重新发明轮子和测试可能的解决方案之前找到正确的方向。

【问题讨论】:

  • 您希望获得多少这些积分? “阈值”由分析确定,可能因系统而异,取决于具体的实现。

标签: arrays c search c11


【解决方案1】:

除了琐碎的案例之外,通常很难预测性能提升在哪里。这就是为什么您应该在更改前后对代码进行基准测试。还可以分析您的代码以找到它花费最多时间的地方。

在其他语言中,这是我分解字典或哈希集的地方。 C 中都不存在,所以我必须权衡添加类似内容的复杂性。

TBH,实现起来并不复杂。如果您需要性能,那是不费吹灰之力。但不保证会更快。

我考虑过对列表进行排序(即先按 X,然后按 Y)。但是考虑到更新的频率,我觉得我会比迭代时更频繁地敲击表格。但是我对排序算法的了解很少。

这很可能不是最优的。但是你可以试试看。你不需要做一个完整的排序。只需进行二分搜索并移动后面的所有内容。

在这里使用某种二叉树会更好吗?还是我会再次花费所有时间重新平衡树?

只有一种方法可以找出答案。尝试并进行基准测试。

理论上,鉴于这些算法的(感知)复杂性,是否存在一个阈值,低于该阈值线性搜索仍然是可行的选择?

我敢肯定,但这些总是必须与现实保持平衡。就像缓存未命中一样,会对性能产生很大影响。可能会提高缓存友好性的一件事可能会发生变化

struct Point {
    int x;
    int y;
};

struct Point pointsOfInterest[1024];

int pointsOfInterest[2][1024];

并将第一个索引用于 x 或 y。可能有效,具体取决于您对数据的处理方式。我想它在你的情况下不起作用,但它可以加速一个只在一个维度上循环的函数。

【讨论】:

  • 更改为int 数组究竟会如何提高缓存性能?现在,您必须在每次 (x,y) 访问时接触两个不同的 1024*sizeof(int) 块,而不是停留在同一个缓存行中。这会导致更糟糕的缓存性能。
  • @Lundin 是的,在这种情况下,情况很可能会更糟。但是,如果您在某些情况下只对 x 或 y 感兴趣,它可能会有所改善。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
相关资源
最近更新 更多