2

我需要创建一个 3D R*-tree,也许是为了长时间存储,但性能也是一个问题。为了创建树,我决定使用 Boost 的 spacialindex 并且基本上找到了两种可能的方法。

或者我直接使用对象创建它,因为它在这里:存储在向量中的多边形索引,但是这不允许我在不再次创建 R*-tree 的情况下存储和加载它。

或者我可以使用此处解释的映射文件:使用 Boost.Interprocess 存储在映射文件中的索引,但是,我不确定在这种情况下查询的性能是否足够好。

我的 r-tree 将包含数千个条目,但很可能少于 100,000 个。现在我的问题是,与使用标准对象相比,使用映射文件是否存在任何强大的性能问题?此外,如果创建大约 100,000 个值的 R*-tree 不需要花费大量时间(我可以将所有边界框和相应的键/数据存储在一个文件中),那么跳过映射文件并在每次运行程序时创建树?

希望有人可以在这里帮助我,因为文档并没有真正提供太多信息(尽管它仍然比 libspacialindex 的文档更好)。

4

2 回答 2

4

映射文件的行为主要类似于常规内存(实际上,在 Linux 中,内存分配使用newmalloc将使用mmap[使用“无文件”支持存储] 作为底层分配方法)。但是,如果您“到处”进行许多小写入,并且您正在映射一个真实文件,那么操作系统将在写入文件之前限制缓冲写入的数量。

不久前提出这个主题时,我做了一些实验,通过调整操作系统如何处理这些“挂起的写入”的设置,即使对于具有随机读/写模式的文件备份内存映射,我也获得了合理的性能[我期望发生的事情当你建造你的树时]。

这是“随机写入的 mmap 性能”问题,我认为这是高度相关的: Bad Linux Memory Mapped File Performance with Random Access C++ & Python (这个答案适用于 Linux - 其他操作系统,尤其是 Windows,可能表现完全不同关于它如何处理对映射文件的写入)

当然,很难说“哪个更好”,在每次程序运行时内存映射文件或重建之间 - 这实际上取决于您的应用程序做什么,是每秒运行 100 次,还是每天运行一次,重建需要多长时间[我完全不知道!],以及许多其他类似的事情。有两种选择:构建最简单的版本,看看它是否“足够快”,或者构建两个版本,然后测量有多少差异,然后决定走哪条路。

我倾向于构建简单(ish)的模型,如果性能不够好,找出慢的地方,然后修复它——这样可以节省大量时间来制作占总执行时间 0.01% 的东西运行快 5 个时钟周期,并在其他地方得到一个大的 thinko,使其运行速度比你预期的慢 500 倍......

于 2015-01-30T08:55:49.050 回答
0

批量加载索引比重复插入快得多,并且会产生更高效的树。因此,如果您可以将所有数据保存在主内存中,我建议使用 STR 批量加载重建树。以我的经验,这已经足够快了(批量加载时间与 I/O 时间相比相形见绌)。

STR 的成本大约是排序的成本。O(n log n)从理论上讲,常数非常低(可能效率较低,O(n log n log n)但仍然相当便宜)。

于 2015-01-30T09:01:53.480 回答