patterncppMinor
Expression template to compute the Euclidean distance
Viewed 0 times
expressiontemplatethecomputeeuclideandistance
Problem
I was writing some geometry-related code again and had a closer look at my function supposed to compute the Euclidean distance between two points (N-dimensional points by the way, hence the
So far, so good. However, one very common operation is to compare the distances. Generally speaking, when comparing the distances, the
My new
Here is a minimal working code at Coliru. Is such a design reasonable or is it overkill to elegantly solve this problem?
N template parameter). Here is a simplified version:template
auto distance(const Point& lhs, const Point& rhs)
-> T
{
T res{};
for (std::size_t i = 0 ; i < N ; ++i)
{
auto tmp = std::abs(lhs[i] - rhs[i]);
res += tmp * tmp;
}
return std::sqrt(res);
}So far, so good. However, one very common operation is to compare the distances. Generally speaking, when comparing the distances, the
sqrt is optimized away and the sum of the squares is compared instead of the distance itself. Therefore, I tried to create some kind of expression template to represent the distance between two points, so that users will benefit from both the ease of use and the "get rid of sqrt optimization" when comparing distances. Basically, the call of sqrt is not done until the exact value of the distance is needed. Here is the class:template
struct DistanceExpression
{
explicit constexpr DistanceExpression(T data):
_data(data)
{}
operator T() const
{
return std::sqrt(_data);
}
bool operator==(const DistanceExpression& other) const
{
return _data == other._data;
}
bool operator!=(const DistanceExpression& other) const
{
return !(*this == other);
}
private:
T _data;
};My new
distance function is implemented as such:template
auto distance(const Point& lhs, const Point& rhs)
-> DistanceExpression
{
T res{};
for (std::size_t i = 0 ; i {res};
}Here is a minimal working code at Coliru. Is such a design reasonable or is it overkill to elegantly solve this problem?
Solution
My concern now is that you make multiple calls to get the actual distance.
Every-time you do that then you incur the expense of the
I suppose it depends on the exact use case of your application which happens more often. But if this is for general code that could be used a lot in either capacity. I would add another two fields to indicate if it was dirty or not and cache the result so you don't have to recompute the actual value each time.
But that has the side affect of adding a conditional branch into the get which can also be expensive when looking at micro optimizations.
Every-time you do that then you incur the expense of the
sqrt() operation.I suppose it depends on the exact use case of your application which happens more often. But if this is for general code that could be used a lot in either capacity. I would add another two fields to indicate if it was dirty or not and cache the result so you don't have to recompute the actual value each time.
But that has the side affect of adding a conditional branch into the get which can also be expensive when looking at micro optimizations.
Context
StackExchange Code Review Q#44589, answer score: 8
Revisions (0)
No revisions yet.