Speeding up parsing of car profile by about 30%

This commit is contained in:
DennisOSRM 2012-11-12 17:00:36 +01:00
parent ac68ff192e
commit 6f8148950e
6 changed files with 73 additions and 65 deletions

View File

@ -36,19 +36,19 @@ public:
HashTable(const unsigned size) { HashTable(const unsigned size) {
table.resize(size); table.resize(size);
} }
void Add(const keyT& key, const valueT& value){ inline void Add(const keyT& key, const valueT& value){
table[key] = value; table[key] = value;
} }
void Set(const keyT& key, const valueT& value){ inline void Set(const keyT& key, const valueT& value){
table[key] = value; table[key] = value;
} }
valueT Find(const keyT& key) const { inline valueT Find(const keyT& key) const {
if(table.find(key) == table.end()) if(table.find(key) == table.end())
return valueT(); return valueT();
return table.find(key)->second; return table.find(key)->second;
} }
bool Holds(const keyT& key) { inline bool Holds(const keyT& key) const {
if(table.find(key) == table.end()) if(table.find(key) == table.end())
return false; return false;
return true; return true;
@ -63,7 +63,7 @@ public:
return valueT(); return valueT();
return table.find(key)->second; return table.find(key)->second;
} }
unsigned Size() const { inline unsigned Size() const {
return table.size(); return table.size();
} }
MyIterator begin() const { MyIterator begin() const {

View File

@ -58,8 +58,7 @@ struct _Way {
isDurationSet = false; isDurationSet = false;
isAccessRestricted = false; isAccessRestricted = false;
ignoreInGrid = false; ignoreInGrid = false;
}
}
enum { enum {
notSure = 0, oneway, bidirectional, opposite notSure = 0, oneway, bidirectional, opposite

View File

@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <boost/spirit/include/karma.hpp>
#include "../DataStructures/Coordinate.h" #include "../DataStructures/Coordinate.h"
// precision: position after decimal point // 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) { static inline void intToString(const int value, std::string & output) {
// The largest 32-bit integer is 4294967295, that is 10 chars // The largest 32-bit integer is 4294967295, that is 10 chars
// On the safe side, add 1 for sign, and 1 for trailing zero // On the safe side, add 1 for sign, and 1 for trailing zero
char buffer[12] ; output.clear();
sprintf(buffer, "%i", value) ; std::back_insert_iterator<std::string> sink(output);
output = buffer ; boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value);
} }
static inline void convertInternalLatLonToString(const int value, std::string & output) { static inline void convertInternalLatLonToString(const int value, std::string & output) {

View File

@ -103,6 +103,7 @@ int main (int argc, char *argv[]) {
luabind::class_<HashTable<std::string, std::string> >("keyVals") luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add) .def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find) .def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [

View File

@ -26,7 +26,6 @@ speed_profile = {
["service"] = 15, ["service"] = 15,
-- ["track"] = 5, -- ["track"] = 5,
["ferry"] = 5, ["ferry"] = 5,
-- ["pier"] = 5,
["default"] = 50 ["default"] = 50
} }
@ -41,16 +40,40 @@ u_turn_penalty = 20
-- End of globals -- End of globals
--find first tag in access hierachy which is set --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 for i,v in ipairs(access_tags_hierachy) do
local tag = source.tags:Find(v) if source.tags:Holds(v) then
if tag ~= '' then --and tag ~= "" then local tag = source.tags:Find(v)
return tag if tag ~= '' then --and tag ~= "" then
return tag
end
end end
end end
return nil return nil
end 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) function node_function (node)
local barrier = node.tags:Find ("barrier") local barrier = node.tags:Find ("barrier")
local access = find_access_tag(node) local access = find_access_tag(node)
@ -74,7 +97,6 @@ function node_function (node)
node.bollard = true node.bollard = true
end end
end end
return 1 return 1
end end
@ -92,8 +114,7 @@ function way_function (way, numberOfNodesInWay)
local ref = way.tags:Find("ref") local ref = way.tags:Find("ref")
local junction = way.tags:Find("junction") local junction = way.tags:Find("junction")
local route = way.tags:Find("route") local route = way.tags:Find("route")
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") ) local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") )
--local man_made = way.tags:Find("man_made")
local barrier = way.tags:Find("barrier") local barrier = way.tags:Find("barrier")
local oneway = way.tags:Find("oneway") local oneway = way.tags:Find("oneway")
local cycleway = way.tags:Find("cycleway") local cycleway = way.tags:Find("cycleway")
@ -113,16 +134,6 @@ function way_function (way, numberOfNodesInWay)
return 0 return 0
end 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 -- Set the name that will be used for instructions
if "" ~= ref then if "" ~= ref then
way.name = ref way.name = ref
@ -137,29 +148,24 @@ function way_function (way, numberOfNodesInWay)
end end
-- Handling ferries and piers -- Handling ferries and piers
if (speed_profile[route] ~= nil and speed_profile[route] > 0)
if (speed_profile[route] ~= nil and speed_profile[route] > 0) --or
--(speed_profile[man_made] ~= nil and speed_profile[man_made] > 0)
then then
if durationIsValid(duration) then if durationIsValid(duration) then
way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) ); way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) );
way.is_duration_set = true; way.is_duration_set = true
end end
way.direction = Way.bidirectional; way.direction = Way.bidirectional
if speed_profile[route] ~= nil then if speed_profile[route] ~= nil then
highway = route; highway = route;
--elseif speed_profile[man_made] ~= nil then
-- highway = man_made;
end end
if not way.is_duration_set then if not way.is_duration_set then
way.speed = speed_profile[highway] way.speed = speed_profile[highway]
end end
end end
-- Set the avg speed on the way if it is accessible by road class -- 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 (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 maxspeed = math.huge
end end
way.speed = math.min(speed_profile[highway], maxspeed) 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 -- Set the avg speed on ways that are marked accessible
if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then 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 maxspeed = math.huge
end end
way.speed = math.min(speed_profile["default"], maxspeed) way.speed = math.min(speed_profile["default"], maxspeed)
@ -206,3 +212,11 @@ function way_function (way, numberOfNodesInWay)
way.type = 1 way.type = 1
return 1 return 1
end 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

View File

@ -26,7 +26,6 @@ speed_profile = {
["service"] = 15, ["service"] = 15,
-- ["track"] = 5, -- ["track"] = 5,
["ferry"] = 5, ["ferry"] = 5,
-- ["pier"] = 5,
["default"] = 50 ["default"] = 50
} }
@ -43,14 +42,24 @@ u_turn_penalty = 20
--find first tag in access hierachy which is set --find first tag in access hierachy which is set
local function find_access_tag(source) local function find_access_tag(source)
for i,v in ipairs(access_tags_hierachy) do for i,v in ipairs(access_tags_hierachy) do
local tag = source.tags:Find(v) if source.tags:Holds(v) then
if tag ~= '' then --and tag ~= "" then local tag = source.tags:Find(v)
return tag if tag ~= '' then --and tag ~= "" then
return tag
end
end end
end end
return nil return nil
end 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) local function parse_maxspeed(source)
if source == nil then if source == nil then
return 0 return 0
@ -62,7 +71,7 @@ local function parse_maxspeed(source)
if string.match(source, "mph") or string.match(source, "mp/h") then if string.match(source, "mph") or string.match(source, "mp/h") then
n = (n*1609)/1000; n = (n*1609)/1000;
end end
return n return math.abs(n)
end end
function node_function (node) function node_function (node)
@ -88,7 +97,6 @@ function node_function (node)
node.bollard = true node.bollard = true
end end
end end
return 1 return 1
end end
@ -107,7 +115,6 @@ function way_function (way, numberOfNodesInWay)
local junction = way.tags:Find("junction") local junction = way.tags:Find("junction")
local route = way.tags:Find("route") local route = way.tags:Find("route")
local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") ) local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") )
--local man_made = way.tags:Find("man_made")
local barrier = way.tags:Find("barrier") local barrier = way.tags:Find("barrier")
local oneway = way.tags:Find("oneway") local oneway = way.tags:Find("oneway")
local cycleway = way.tags:Find("cycleway") local cycleway = way.tags:Find("cycleway")
@ -127,16 +134,6 @@ function way_function (way, numberOfNodesInWay)
return 0 return 0
end 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 -- Set the name that will be used for instructions
if "" ~= ref then if "" ~= ref then
way.name = ref way.name = ref
@ -151,29 +148,24 @@ function way_function (way, numberOfNodesInWay)
end end
-- Handling ferries and piers -- Handling ferries and piers
if (speed_profile[route] ~= nil and speed_profile[route] > 0)
if (speed_profile[route] ~= nil and speed_profile[route] > 0) --or
--(speed_profile[man_made] ~= nil and speed_profile[man_made] > 0)
then then
if durationIsValid(duration) then if durationIsValid(duration) then
way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) ); way.speed = math.max( parseDuration(duration) / math.max(1, numberOfNodesInWay-1) );
way.is_duration_set = true; way.is_duration_set = true
end end
way.direction = Way.bidirectional; way.direction = Way.bidirectional
if speed_profile[route] ~= nil then if speed_profile[route] ~= nil then
highway = route; highway = route;
--elseif speed_profile[man_made] ~= nil then
-- highway = man_made;
end end
if not way.is_duration_set then if not way.is_duration_set then
way.speed = speed_profile[highway] way.speed = speed_profile[highway]
end end
end end
-- Set the avg speed on the way if it is accessible by road class -- 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 (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 maxspeed = math.huge
end end
way.speed = math.min(speed_profile[highway], maxspeed) 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 -- Set the avg speed on ways that are marked accessible
if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then 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 maxspeed = math.huge
end end
way.speed = math.min(speed_profile["default"], maxspeed) way.speed = math.min(speed_profile["default"], maxspeed)