From 6f8148950ec546905dbf3cf84c5eebee810e04a3 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Mon, 12 Nov 2012 17:00:36 +0100 Subject: [PATCH] Speeding up parsing of car profile by about 30% --- DataStructures/HashTable.h | 10 +++--- Extractor/ExtractorStructs.h | 3 +- Util/StringUtil.h | 8 +++-- extractor.cpp | 1 + profile.lua | 70 +++++++++++++++++++++--------------- profiles/car.lua | 46 ++++++++++-------------- 6 files changed, 73 insertions(+), 65 deletions(-) diff --git a/DataStructures/HashTable.h b/DataStructures/HashTable.h index 20f9749fd..57c2dde9f 100644 --- a/DataStructures/HashTable.h +++ b/DataStructures/HashTable.h @@ -36,19 +36,19 @@ public: HashTable(const unsigned size) { table.resize(size); } - void Add(const keyT& key, const valueT& value){ + inline void Add(const keyT& key, const valueT& value){ table[key] = value; } - void Set(const keyT& key, const valueT& value){ + inline void Set(const keyT& key, const valueT& value){ table[key] = value; } - valueT Find(const keyT& key) const { + inline valueT Find(const keyT& key) const { if(table.find(key) == table.end()) return valueT(); return table.find(key)->second; } - bool Holds(const keyT& key) { + inline bool Holds(const keyT& key) const { if(table.find(key) == table.end()) return false; return true; @@ -63,7 +63,7 @@ public: return valueT(); return table.find(key)->second; } - unsigned Size() const { + inline unsigned Size() const { return table.size(); } MyIterator begin() const { diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index 6560dbd21..ebd40fc66 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -58,8 +58,7 @@ struct _Way { isDurationSet = false; isAccessRestricted = false; ignoreInGrid = false; - - } + } enum { notSure = 0, oneway, bidirectional, opposite diff --git a/Util/StringUtil.h b/Util/StringUtil.h index 6024a9697..d78eadd81 100644 --- a/Util/StringUtil.h +++ b/Util/StringUtil.h @@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include +#include + #include "../DataStructures/Coordinate.h" // precision: position after decimal point @@ -61,9 +63,9 @@ static inline char* printInt( char* buffer, int value ) { static inline void intToString(const int value, std::string & output) { // The largest 32-bit integer is 4294967295, that is 10 chars // On the safe side, add 1 for sign, and 1 for trailing zero - char buffer[12] ; - sprintf(buffer, "%i", value) ; - output = buffer ; + output.clear(); + std::back_insert_iterator sink(output); + boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value); } static inline void convertInternalLatLonToString(const int value, std::string & output) { diff --git a/extractor.cpp b/extractor.cpp index 5952e2aaa..ecee22302 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -103,6 +103,7 @@ int main (int argc, char *argv[]) { luabind::class_ >("keyVals") .def("Add", &HashTable::Add) .def("Find", &HashTable::Find) + .def("Holds", &HashTable::Holds) ]; luabind::module(myLuaState) [ diff --git a/profile.lua b/profile.lua index a9f3a455c..b2291c1b0 100644 --- a/profile.lua +++ b/profile.lua @@ -26,7 +26,6 @@ speed_profile = { ["service"] = 15, -- ["track"] = 5, ["ferry"] = 5, --- ["pier"] = 5, ["default"] = 50 } @@ -41,16 +40,40 @@ u_turn_penalty = 20 -- End of globals --find first tag in access hierachy which is set -function find_access_tag(source) +local function find_access_tag(source) for i,v in ipairs(access_tags_hierachy) do - local tag = source.tags:Find(v) - if tag ~= '' then --and tag ~= "" then - return tag + if source.tags:Holds(v) then + local tag = source.tags:Find(v) + if tag ~= '' then --and tag ~= "" then + return tag + end end end return nil end +local function find_in_keyvals(keyvals, tag) + if keyvals:Holds(tag) then + return keyvals:Find(tag) + else + return nil + end +end + +local function parse_maxspeed(source) + if source == nil then + return 0 + end + local n = tonumber(source) + if n == nil then + n = 0 + end + if string.match(source, "mph") or string.match(source, "mp/h") then + n = (n*1609)/1000; + end + return math.abs(n) +end + function node_function (node) local barrier = node.tags:Find ("barrier") local access = find_access_tag(node) @@ -74,7 +97,6 @@ function node_function (node) node.bollard = true end end - return 1 end @@ -92,8 +114,7 @@ function way_function (way, numberOfNodesInWay) local ref = way.tags:Find("ref") local junction = way.tags:Find("junction") local route = way.tags:Find("route") - local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") ) - --local man_made = way.tags:Find("man_made") + local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") ) local barrier = way.tags:Find("barrier") local oneway = way.tags:Find("oneway") local cycleway = way.tags:Find("cycleway") @@ -113,16 +134,6 @@ function way_function (way, numberOfNodesInWay) return 0 end - - -- Check if our vehicle types are forbidden --- for i,v in ipairs(access_tags) do --- local mode_value = way.tags:Find(v) --- if nil ~= mode_value and "no" == mode_value then --- return 0; --- end --- end - - -- Set the name that will be used for instructions if "" ~= ref then way.name = ref @@ -137,29 +148,24 @@ function way_function (way, numberOfNodesInWay) end -- Handling ferries and piers - - if (speed_profile[route] ~= nil and speed_profile[route] > 0) --or - --(speed_profile[man_made] ~= nil and speed_profile[man_made] > 0) + if (speed_profile[route] ~= nil and speed_profile[route] > 0) then if durationIsValid(duration) then way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) ); - way.is_duration_set = true; + way.is_duration_set = true end - way.direction = Way.bidirectional; + way.direction = Way.bidirectional if speed_profile[route] ~= nil then highway = route; - --elseif speed_profile[man_made] ~= nil then - -- highway = man_made; end if not way.is_duration_set then way.speed = speed_profile[highway] end - end -- Set the avg speed on the way if it is accessible by road class if (speed_profile[highway] ~= nil and way.speed == -1 ) then - if (0 < maxspeed and not take_minimum_of_speeds) or (maxspeed == 0) then + if 0 == maxspeed then maxspeed = math.huge end way.speed = math.min(speed_profile[highway], maxspeed) @@ -167,7 +173,7 @@ function way_function (way, numberOfNodesInWay) -- Set the avg speed on ways that are marked accessible if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then - if (0 < maxspeed and not take_minimum_of_speeds) or maxspeed == 0 then + if 0 == maxspeed then maxspeed = math.huge end way.speed = math.min(speed_profile["default"], maxspeed) @@ -206,3 +212,11 @@ function way_function (way, numberOfNodesInWay) way.type = 1 return 1 end + +-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT + +function node_vector_function(vector) + for v in vector.nodes do + node_function(v) + end +end diff --git a/profiles/car.lua b/profiles/car.lua index 2b723fa93..b2291c1b0 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -26,7 +26,6 @@ speed_profile = { ["service"] = 15, -- ["track"] = 5, ["ferry"] = 5, --- ["pier"] = 5, ["default"] = 50 } @@ -43,14 +42,24 @@ u_turn_penalty = 20 --find first tag in access hierachy which is set local function find_access_tag(source) for i,v in ipairs(access_tags_hierachy) do - local tag = source.tags:Find(v) - if tag ~= '' then --and tag ~= "" then - return tag + if source.tags:Holds(v) then + local tag = source.tags:Find(v) + if tag ~= '' then --and tag ~= "" then + return tag + end end end return nil end +local function find_in_keyvals(keyvals, tag) + if keyvals:Holds(tag) then + return keyvals:Find(tag) + else + return nil + end +end + local function parse_maxspeed(source) if source == nil then return 0 @@ -62,7 +71,7 @@ local function parse_maxspeed(source) if string.match(source, "mph") or string.match(source, "mp/h") then n = (n*1609)/1000; end - return n + return math.abs(n) end function node_function (node) @@ -88,7 +97,6 @@ function node_function (node) node.bollard = true end end - return 1 end @@ -107,7 +115,6 @@ function way_function (way, numberOfNodesInWay) local junction = way.tags:Find("junction") local route = way.tags:Find("route") local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") ) - --local man_made = way.tags:Find("man_made") local barrier = way.tags:Find("barrier") local oneway = way.tags:Find("oneway") local cycleway = way.tags:Find("cycleway") @@ -127,16 +134,6 @@ function way_function (way, numberOfNodesInWay) return 0 end - - -- Check if our vehicle types are forbidden --- for i,v in ipairs(access_tags) do --- local mode_value = way.tags:Find(v) --- if nil ~= mode_value and "no" == mode_value then --- return 0; --- end --- end - - -- Set the name that will be used for instructions if "" ~= ref then way.name = ref @@ -151,29 +148,24 @@ function way_function (way, numberOfNodesInWay) end -- Handling ferries and piers - - if (speed_profile[route] ~= nil and speed_profile[route] > 0) --or - --(speed_profile[man_made] ~= nil and speed_profile[man_made] > 0) + if (speed_profile[route] ~= nil and speed_profile[route] > 0) then if durationIsValid(duration) then way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) ); - way.is_duration_set = true; + way.is_duration_set = true end - way.direction = Way.bidirectional; + way.direction = Way.bidirectional if speed_profile[route] ~= nil then highway = route; - --elseif speed_profile[man_made] ~= nil then - -- highway = man_made; end if not way.is_duration_set then way.speed = speed_profile[highway] end - end -- Set the avg speed on the way if it is accessible by road class if (speed_profile[highway] ~= nil and way.speed == -1 ) then - if (0 < maxspeed and not take_minimum_of_speeds) or (maxspeed == 0) then + if 0 == maxspeed then maxspeed = math.huge end way.speed = math.min(speed_profile[highway], maxspeed) @@ -181,7 +173,7 @@ function way_function (way, numberOfNodesInWay) -- Set the avg speed on ways that are marked accessible if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then - if (0 < maxspeed and not take_minimum_of_speeds) or maxspeed == 0 then + if 0 == maxspeed then maxspeed = math.huge end way.speed = math.min(speed_profile["default"], maxspeed)