为什么boost :: geometry :: distance与model :: d2 :: point_xy <float>返回double而不是float?

时间:2015-05-01 07:50:02

标签: c++ performance boost boost-geometry

我将sschuberth boost::geometry::distance参数的性能与等效的直接2D实现进行了比较:

model::d2::point_xy<float>

(参见http://rextester.com/NTOVR83857处的整个基准)。我发现在所有主要的C ++编译器中,boost版本的速度一直很慢:

  • 1.77x for gcc
  • 1.47x for clang
  • 1.51x for vc ++

我尝试使用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

2 个答案:

答案 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)

返回类型取决于策略:http://www.boost.org/doc/libs/1_58_0/libs/geometry/doc/html/geometry/design.html#geometry.design.return_type

这使我认为您可以通过策略明确指定计算类型:

<强> 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指令集上进行全面优化时。