我将sschuberth
boost::geometry::distance
参数的性能与等效的直接2D实现进行了比较:
model::d2::point_xy<float>
(参见http://rextester.com/NTOVR83857处的整个基准)。我发现在所有主要的C ++编译器中,boost版本的速度一直很慢:
我尝试使用struct Point {
float x, y;
float distance(const Point& p) const {return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));}
};
点坐标进行相同的基准测试,其中boost在没有开销的情况下执行。我注意到带有double
参数的boost::geometry::distance
返回model::d2::point_xy<float>
,这似乎是减速的原因。为什么它没有返回double
?
答案 0 :(得分:1)
由于boost使用模板,因此需要确保返回类型具有足够的精度。想象一下,如果输入点具有X和Y的整数值 - 结果需要超过整数精度。此外,如果输入Point使用X和Y的双精度值,则float
的结果将不够精确。因此,似乎double
被选为具有足够精度的全部捕获。
这里给出了距离模板设计的基本原理:
http://www.boost.org/doc/libs/1_58_0/libs/geometry/doc/html/geometry/design.html
答案 1 :(得分:1)
这使我认为您可以通过策略明确指定计算类型:
<强> Live On Coliru 强>
#include <iostream>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/algorithms/distance.hpp>
#include <boost/geometry/strategies/distance.hpp>
int main() {
using namespace boost::geometry;
using P = model::d2::point_xy<float>;
using V = traits::coordinate_type<P>::type;
std::cout << "Coordinate type: " << typeid(V).name() << "\n";
P a, b;
std::cout << "Calculation type: " << typeid(default_distance_result<P, P>::calculation_type).name() << "\n";
std::cout << "Result type: " << typeid(default_distance_result<P, P>::type).name() << "\n";
using S = strategy::distance::pythagoras<V>;
std::cout << "Calculation type: " << typeid(distance_result<P, P, S>::calculation_type).name() << "\n";
std::cout << "Result type: " << typeid(distance_result<P, P, S>::type).name() << "\n";
static_assert(boost::is_same<distance_result<P, P, S>::type, float>::value, "oops");
}
打印(通过c++filt -t
传送):
Coordinate type: float
Calculation type: boost::geometry::strategy::distance::pythagoras<void>::calculation_type<boost::geometry::model::d2::point_xy<float, boost::geometry::cs::cartesian>, boost::geometry::model::d2::point_xy<float, boost::geometry::cs::cartesian> >
Result type: double
Calculation type: boost::geometry::strategy::distance::pythagoras<float>::calculation_type<boost::geometry::model::d2::point_xy<float, boost::geometry::cs::cartesian>, boost::geometry::model::d2::point_xy<float, boost::geometry::cs::cartesian> >
Result type: float
注意由于精度有限而可能会被剪裁的结果精度。这非常符合精度/存储效率的折衷。
我实际上期望在double
到处(而不是float
)发生最佳性能,尤其是在现代CPU指令集上进行全面优化时。