Project-OSRM / osrm-backend

Open Source Routing Machine - C++ backend
http://map.project-osrm.org
BSD 2-Clause "Simplified" License
6.41k stars 3.39k forks source link

only call lua node functions if relevant tags are present #4152

Open emiltin opened 7 years ago

emiltin commented 7 years ago

inspired by #4147, what about the profile providing a list of tags, and only calling the node function if at least one of the tags are present? the node functions typically look at a limited number of tags. e.g. the car profile:

function node_function (node, result)
  -- parse access and barrier tags
  local access = find_access_tag(node, profile.access_tags_hierarchy)
  if access then
    if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then
      result.barrier = true
    end
  else
    local barrier = node:get_value_by_key("barrier")
    if barrier then
      --  make an exception for rising bollard barriers
      local bollard = node:get_value_by_key("bollard")
      local rising_bollard = bollard and "rising" == bollard

      if not profile.barrier_whitelist[barrier] and not rising_bollard then
        result.barrier = true
      end
    end
  end

  -- check if node is a traffic light
  local tag = node:get_value_by_key("highway")
  if "traffic_signals" == tag then
    result.traffic_lights = true
  end
end

which only looks at the tags: access, vehicle, motor-vehicle,vehicle, barrier, bollard, highway if none of these tags are present, there's no need to call the node function.

daniel-j-h commented 7 years ago

@emiltin yep the idea came up during discussion, too. Basically the idea is to pull out a list of tags from Lua into C++ and then do the fast tag comparison on the C++ side already. @danpat and @joto found the approach in #4147 to be sufficient for a first try and easy to implement.

danpat commented 7 years ago

There are definitely some more speedups to be had with this general approach, but the improvements will be less significant than the tagless node filtering. I noted some other experiments I did here https://github.com/Project-OSRM/osrm-backend/pull/4147#issuecomment-308047549

Basically, for the planet we have 4.6 billion nodes, only 180 million of which have any tags. That's ~4.3 billion node_function calls we can avoid. In comparison, doing tag checking on the remaining nodes or ways will reduce the call count by a few million, a much less significant saving, and the tag check itself is not completely free. I did some hard-coded testing and I saw ~8-10% speedups by filtering out way tags like buildings or checking for access/highway on nodes.

It's worth keeping this ticket though, I think it's generally a decent further optimization.

emiltin commented 7 years ago

yes, it would be a smaller gain