You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The majority of time is taken (nearly 40%) in the thread is in mapbox::vector_tile::extract_geometry due to calls to new and delete (memory allocation and deallocation)
Per the title, one idea to solve the mapbox::vector_tile::extract_geometry bottleneck is to avoid calling it for geometries outside the radius. To do this you could:
Add mapbox::vector_tile::extract_bbox which would accumulate and return a bbox without decoding all vertexes of polygons/lines into sub-arrays (to avoid the memory allocation and deallocation cost of heap allocation of std::vector inside of geometry.hpp)
Check for situations where the distance from the bbox to the query point is > radius and return early, skipping decoding geometries and skipping calling closest_point in those cases.
This would lead to the vtzero handlers getting called twice, so there would be that added cost. But my hope/hunch is that this cost would be small and worth it. Thoughts?
To save some cost from decoding the vtzero geometry twice you can return early. Instead of calculating the bbox in the first go you could, say, detect that some points of the geometry are to the left of the query point and when you find the first point that's to the right of the query point, you can stop there and directly go to the more detailed check. Makes the code more complex though.
If memory allocation is the culprit here, find a way to re-use memory. You are only looking at one feature/geometry at a time, so the same memory can be reused for every geometry. Of course this doesn't work with vector-tile geometries.
Instead of calculating the bbox in the first go you could, say, detect that some points of the geometry are to the left of the query point and when you find the first point that's to the right of the query point, you can stop there and directly go to the more detailed check. Makes the code more complex though.
@joto - this sounds very interesting. Could you share a little more detail on how this could work? How would we be able to do these point detections without decoding the vtzero geometry twice? Are you saying that we could do these while doing the current decode somehow (perhaps within our geometry handler)? This feels a little bit similar to mapbox/mapnik-vector-tile#146 where, per geometry part/ring we would check if that ring was outside the bbox filter and then avoid adding it to the vector containing all rings.
If memory allocation is the culprit here, find a way to re-use memory. You are only looking at one feature/geometry at a time, so the same memory can be reused for every geometry. Of course this doesn't work with vector-tile geometries.
Yes, I had this same thought. Currently we don't need to carry through the geometry at all - we simply create each geometry in the loop and then discard. So, unless @mapsam anticipates needing to return the geometry to the user, we could potentially do this and save significant memory allocations. I presume we'd need to, however, templatize all the vector-tile 2.x functions to accept a custom geometry type that overrides the allocator? /cc @flippmoke - ideas on how this could be done?
@springmeyer To do any of this you have to rid yourself of the convenience of the vector-tile functionality and use vtzero directly. This way you have access to the undecoded geometry and can decode it "manually" stopping the moment you find a point that makes it possible that the whole geometry is "near enough" to the query point. Only then you assemble the actual geometry. For points this is all very simple and you don't need vector-tile at all I would think. For more complex geometry the nearness calculation is more difficult to do, I am not sure what the best approach would be there. Maybe mapbox/vector-tile#36 would already help here.
Activity
springmeyer commentedon Jan 24, 2018
Per the title, one idea to solve the
mapbox::vector_tile::extract_geometrybottleneck is to avoid calling it for geometries outside the radius. To do this you could:mapbox::vector_tile::extract_bboxwhich would accumulate and return a bbox without decoding all vertexes of polygons/lines into sub-arrays (to avoid the memory allocation and deallocation cost of heap allocation ofstd::vectorinside ofgeometry.hpp)closest_pointin those cases.This would lead to the vtzero handlers getting called twice, so there would be that added cost. But my hope/hunch is that this cost would be small and worth it. Thoughts?
mapsam commentedon Jan 24, 2018
Hey @springmeyer just to confirm, were these run on master or dedupe branch?
springmeyer commentedon Jan 24, 2018
@mapsam - dedupe
joto commentedon Jan 29, 2018
Two ideas here:
vector-tilegeometries.springmeyer commentedon Feb 2, 2018
@joto - this sounds very interesting. Could you share a little more detail on how this could work? How would we be able to do these point detections without decoding the vtzero geometry twice? Are you saying that we could do these while doing the current decode somehow (perhaps within our geometry handler)? This feels a little bit similar to mapbox/mapnik-vector-tile#146 where, per geometry part/ring we would check if that ring was outside the bbox filter and then avoid adding it to the vector containing all rings.
springmeyer commentedon Feb 2, 2018
Yes, I had this same thought. Currently we don't need to carry through the geometry at all - we simply create each geometry in the loop and then discard. So, unless @mapsam anticipates needing to return the geometry to the user, we could potentially do this and save significant memory allocations. I presume we'd need to, however, templatize all the vector-tile 2.x functions to accept a custom geometry type that overrides the allocator? /cc @flippmoke - ideas on how this could be done?
mapsam commentedon Feb 2, 2018
Nope!
joto commentedon Feb 2, 2018
@springmeyer To do any of this you have to rid yourself of the convenience of the
vector-tilefunctionality and usevtzerodirectly. This way you have access to the undecoded geometry and can decode it "manually" stopping the moment you find a point that makes it possible that the whole geometry is "near enough" to the query point. Only then you assemble the actual geometry. For points this is all very simple and you don't needvector-tileat all I would think. For more complex geometry the nearness calculation is more difficult to do, I am not sure what the best approach would be there. Maybe mapbox/vector-tile#36 would already help here.artemp commentedon Jul 4, 2018
Might be relevant here : mapbox/vtcomposite#55
springmeyer commentedon Dec 3, 2018
More bbox filtering applied in mapbox/vtcomposite#91 to vcomposite