为什么 boost::geometry::distance 和 model::d2::point_xy<float> returns 是 double 而不是 float?

Why boost::geometry::distance with model::d2::point_xy<float> returns a double not a float?

我将 boost::geometry::distancemodel::d2::point_xy<float> 参数上的性能与等效的直接 2D 实现进行了比较:

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));}
};

(请参阅 http://rextester.com/NTOVR83857 处的整个基准测试)。我发现 boost 版本在所有主要的 C++ 编译器中始终较慢:

我用 double 点坐标尝试了相同的基准测试,其中执行了没有开销的提升。我注意到 boost::geometry::distance with model::d2::point_xy<float> arguments returns a double,这似乎是减速的原因。为什么它不返回 float?

由于boost使用的是模板,所以需要保证return类型有足够的精度。想象一下,如果输入 Points 具有 X 和 Y 的整数值——结果需要的不仅仅是整数精度。此外,如果输入点对 X 和 Y 使用双精度值,则 float 的结果将不够精确。因此,似乎选择 double 作为具有足够精度的包罗万象。

此处给出距离模板设计的基本原理:

http://www.boost.org/doc/libs/1_58_0/libs/geometry/doc/html/geometry/design.html

return 类型取决于策略: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

注意结果精度可能会因为精度有限而被削减。这在很大程度上是 precision/storage 效率权衡。

我实际上希望 double 无处不在(而不是 float),尤其是对现代 CPU 指令集进行全面优化时,性能最好。