- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我测试了 boost.geometry.index.rtree (boost 1.59 www.boost.org) 和 superliminal.RTree ( http://superliminal.com/sources/sources.htm#C_Code )。
令我惊讶的是,superliminal.RTree 比 boost.geometry.index.rtree 更快。
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point < int, 2, bg::cs::cartesian > point_t;
typedef bg::model::box < point_t > box_t;
typedef std::pair < box_t, uint64_t > value_t;
typedef bgi::rtree < value_t, bgi::quadratic < 8, 4 > > rtree_t;
结果是:
superliminal.RTree 0.029s
boost.geometry.index.rtree 0.12s.
最佳答案
很难说出为什么在您的情况下速度较慢,因为您没有共享代码,也没有说明两个 R 树实现的确切使用方式。您还没有提供有关您存储的数据的任何信息。当您比较算法或数据结构时,这些事情非常重要。
我只能猜测您使用 Superliminar R-tree 的方式与在附加的测试文件中使用的方式相同,因此您将回调函数传递给 Search
成员函数。我猜您正在使用 Boost.Geometry R-tree 的方式与快速入门部分文档中显示的方式相同,因此您传递的是 std::back_insert_iterator
的对象。进入query
成员函数。因此,让我们检查一下。
#include "RTree.h"
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/timer.hpp>
struct Rect
{
Rect() {}
Rect(int a_minX, int a_minY, int a_maxX, int a_maxY)
{
min[0] = a_minX;
min[1] = a_minY;
max[0] = a_maxX;
max[1] = a_maxY;
}
int min[2];
int max[2];
};
// used with Superliminar R-tree
std::vector<uint64_t> res;
bool MySearchCallback(uint64_t id, void* arg)
{
res.push_back(id);
return true;
}
int main()
{
// randomize rectangles
std::vector<Rect> rects;
for (size_t i = 0 ; i < 300000 ; ++i)
{
int min_x = rand() % 10000;
int min_y = rand() % 10000;
int w = 1 + rand() % 100;
int h = 1 + rand() % 100;
rects.push_back(Rect(min_x, min_y, min_x+w, min_y+h));
}
// create the rectangle passed into the query
Rect search_rect(4000, 4000, 6000, 6000);
// create the Superliminar R-tree
RTree<uint64_t, int, 2, int64_t> tree;
// create the Boost.Geometry R-tree
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<int, 2, bg::cs::cartesian> point_t;
typedef bg::model::box<point_t> box_t;
typedef std::pair<box_t, uint64_t> value_t;
bgi::rtree<value_t, bgi::quadratic<8, 4> > bg_tree;
// Insert values
for(size_t i = 0; i < rects.size(); i++)
{
Rect const& r = rects[i];
tree.Insert(r.min, r.max, i);
box_t b(point_t(r.min[0], r.min[1]), point_t(r.max[0], r.max[1]));
bg_tree.insert(value_t(b, i));
}
// test Rtree
{
int sum = 0;
boost::timer t;
for (size_t i = 0 ; i < 100 ; ++i)
{
res.clear();
sum += tree.Search(search_rect.min, search_rect.max, MySearchCallback, NULL);
}
double s = t.elapsed();
std::cout << s << " " << sum << std::endl;
}
// test BG Rtree
{
box_t search_box(
point_t(search_rect.min[0], search_rect.min[1]),
point_t(search_rect.max[0], search_rect.max[1]));
size_t sum = 0;
boost::timer t;
for (size_t i = 0 ; i < 100 ; ++i)
{
std::vector<value_t> res;
sum += bg_tree.query(bgi::intersects(search_box), std::back_inserter(res));
}
double s = t.elapsed();
std::cout << s << " " << sum << std::endl;
}
}
结果(使用 GCC 4.8 -O2 -finline-functions)是:
0.014s for Superliminar R-tree
0.072s for Boost.Geometry R-tree
因此它们与您的相似,即一个快约 5 倍。请注意,在这两种情况下,我都创建了一个容器来存储结果(Superliminar 的 ID 和 Boost.Geometry 的整个值)。问题是 R 树的使用方式不同。
优化一
让我们尝试通过以相同的方式存储相同的结果来消除两种 R 树在使用上的差异。为此删除临时 std::vector<value_t>
.实现回调替换 std::back_insert_iterator
使用一个名为 boost::function_output_iterator
的函数对象.在这两种情况下,仅将 ID 存储在 std::vector<uint64_t>
中希望编译器能优化代码。
#include "RTree.h"
#include <vector>
#include <boost/function_output_iterator.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/timer.hpp>
struct Rect
{
Rect() {}
Rect(int a_minX, int a_minY, int a_maxX, int a_maxY)
{
min[0] = a_minX;
min[1] = a_minY;
max[0] = a_maxX;
max[1] = a_maxY;
}
int min[2];
int max[2];
};
std::vector<uint64_t> res;
// used with Superliminar R-tree
bool MySearchCallback(uint64_t id, void* arg)
{
res.push_back(id);
return true;
}
// used with Boost.Geometry R-tree
struct MySearchCallback2
{
template <typename Value>
void operator()(Value const& v)
{
res.push_back(v.second);
}
};
int main()
{
// randomize rectangles
std::vector<Rect> rects;
for (size_t i = 0 ; i < 300000 ; ++i)
{
int min_x = rand() % 10000;
int min_y = rand() % 10000;
int w = 1 + rand() % 100;
int h = 1 + rand() % 100;
rects.push_back(Rect(min_x, min_y, min_x+w, min_y+h));
}
// create the rectangle passed into the query
Rect search_rect(4000, 4000, 6000, 6000);
// create the Superliminar R-tree
RTree<uint64_t, int, 2, int64_t> tree;
// create the Boost.Geometry R-tree
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<int, 2, bg::cs::cartesian> point_t;
typedef bg::model::box<point_t> box_t;
typedef std::pair<box_t, uint64_t> value_t;
bgi::rtree<value_t, bgi::quadratic<8, 4> > bg_tree;
// Insert values
for(size_t i = 0; i < rects.size(); i++)
{
Rect const& r = rects[i];
tree.Insert(r.min, r.max, i);
box_t b(point_t(r.min[0], r.min[1]), point_t(r.max[0], r.max[1]));
bg_tree.insert(value_t(b, i));
}
// test Rtree
{
int sum = 0;
boost::timer t;
for (size_t i = 0 ; i < 100 ; ++i)
{
res.clear();
sum += tree.Search(search_rect.min, search_rect.max, MySearchCallback, NULL);
}
double s = t.elapsed();
std::cout << s << " " << sum << std::endl;
}
// test BG Rtree
{
box_t search_box(
point_t(search_rect.min[0], search_rect.min[1]),
point_t(search_rect.max[0], search_rect.max[1]));
size_t sum = 0;
MySearchCallback2 callback;
boost::timer t;
for (size_t i = 0 ; i < 100 ; ++i)
{
res.clear();
sum += bg_tree.query(bgi::intersects(search_box), boost::make_function_output_iterator(callback));
}
double s = t.elapsed();
std::cout << s << " " << sum << std::endl;
}
}
在这种情况下,结果是:
0.014s for Superliminar R-tree
0.033s for Boost.Geometry R-tree
优化2
可以做的另一件事是禁用断言。 Boost.Geometry R 树中有一些。用 -DNDEBUG
编译代码后结果更接近:
0.014s for Superliminar R-tree
0.015s for Boost.Geometry R-tree
结论
在这个综合测试用例中,对于随机数据等,结果或多或少是相同的。同样,对于您来说它们可能有所不同,我不知道您到底在做什么,所以我无法告诉您问题出在哪里。
这是一个非常简单的用例,如果测试更复杂的用例,结果可能会有所不同。换句话说,应该分析一个现实生活中的应用程序,看看是否存在瓶颈。
此外,Boost.Geometry R-tree 的代码要复杂得多。两种 R-tree 实现的接口(interface)是不同的,特别是搜索/查询功能需要不同的参数,并且肯定会以不同的方式处理它们。编译器可能会选择以不同方式优化代码。
附言
借助 Boost.Geometry R 树,可以使用不同的拆分算法和打包算法,因此您可以试验哪一种最适合您的情况。要使用打包算法,您必须将一系列值传递给 rtree 构造函数。对于相同的数据和元素数量以及使用打包算法创建的 rtree,查询时间为 0.005s
对我来说。
关于c++ - 为什么 boost.geometry.index.rtree 比 superliminal.RTree 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33005712/
我测试了 boost.geometry.index.rtree (boost 1.59 www.boost.org) 和 superliminal.RTree ( http://superlimina
我正在尝试在 python 中剪辑空间数据,但是当我运行我的代码时...... europe = gpd.clip(worldmap, europe_bound_gdf) ...我收到错误: ( Im
这是我的代码片段。我正在尝试为顶点类对象 RTreeVertex 创建一个 rtree 树。 class Entity { public: int num; public: Entity(in
我想完全理解 Java 上的二维 RTree,但我在解释中迷路了,我希望有人能告诉我它们是如何工作的。 我对他们的了解是这样的: 您从具有最大条目数 M 的节点列表开始,当您尝试获得更多值时,您必须拆
我正在尝试了解 RTree 算法的基础知识,并且正在尝试弄清楚它是如何执行搜索的,例如1 公里内的所有餐厅。我们会将所有对象存储在数据库中的矩形中,然后我们(可能)会根据我们当前的位置构建一个查询矩形
我需要构建一个 R树使用给定的数据点。我已经搜索了 R 树的实现。当给定矩形坐标作为输入时,我发现所有实现都构建了 r 树。当给定数据点本身时,我需要构建 r 树(它可以是一维的)。代码应该负责创建包
我很疑惑。考虑以下代码,稍微改编自 http://www.boost.org/doc/libs/1_57_0/libs/geometry/doc/html/geometry/spatial_index
我一直在尝试调试使用 Pythons RTree version 0.8.2 的软件包中的一些奇怪行为. 为了跟踪问题,我需要每隔几分钟序列化一次 RTree 实例,当问题发生时我可以得到一个非常准确
我正在关注 boost geometry rtree文档。我能够使用一个框执行空间查询,以检索与其相交的 rtree 元素列表。 我想知道是否有一种方法可以在 rtree 和另一个 rtree(相同类
我使用 OpenCv 进行图像分类。训练后我将模型保存到 *.yaml.gz。然后我将这个文件添加到嵌入式资源中。现在我需要从资源加载模型,但 OpenCv 只允许从文件或字符串加载。 HMODULE
我正在 heroku 上部署一个 GIS 应用程序。我在我的电脑上开发了它,当我部署它时,rtree 不见了。我无法通过 pip 安装它,因为 pip 安装有问题,正如 rtree 开发人员自己所说的
我正在尝试使用Rtree并面对这种奇怪的行为:INSERT语句在普通表中正常工作,但在rtree表中却失败了: 这个例子很好用: DROP TABLE IF EXISTS ltssoffsets; C
我想使用 Boost C++ 库找到在 rtree 中索引的所有元素,这些元素与带孔的多边形的外环相交但不完全在任何孔内。 我知道如何让元素与外环相交: // Constructing the ext
经过一些阅读后,我了解到层次结构遍历虽然可能在 boost rtree 中并未得到官方支持。我有几个不同的用例,我可以在没有层次结构遍历的情况下进行管理,但我不确定效率。因此,我正在寻求有关 boos
将新框插入 rtree 时,我想首先检查树中是否已经存在相同的框。如果是,我只想获取该值,否则我需要插入一个新值。执行此操作的最佳(即最有效)方法是什么? 我可以通过调用 nearest(box,1)
我正在尝试在我的一个项目中使用 boost::geometry 的 rtree DS,但我发现很难浏览文档。某些方法的文档很少,我找不到足够的例子。现在,我正在尝试构建示例程序,以便进一步构建它。 因
Pickling Rtree 看起来并不简单,因为它是一个 ctypes 包装器。 This comment在 SO 秒假设。 但是,在(很多)旧的@sgillies post (这个库的作者),在评
我在 5 维空间中有大约 10 K 个点。我们可以假设这些点随机分布在空间 (0,0,0,0,0) 和 (100,100,100,100,100) 中。显然,整个数据集可以很容易地驻留在内存中。 我想
Boost rtree 为某些与段查询的交集给出了错误的交集结果。在这种情况下,边界框是 y=0 处的 y 平面 10x10 正方形。我正在查询从 (2, 1, 0) 到 (2, 1, 10) 的 z
我有一个城市的简化 map ,其中有街道作为线串,地址作为点。我需要找到从每个点到任何街道线的最近路径。我有一个执行此操作的工作脚本,但它在多项式时间内运行,因为它嵌套了 for 循环。对于 150
我是一名优秀的程序员,十分优秀!