I am currently learning C++ and in doing so I am converting the A* path-finding algorithm that I previously wrote in Python to C++. I just decided to plunge in despite not knowing much about all the different kinds of data-types in the C++ libraries.
After finishing writing the program, the C++ version runs way slower than the Python version (the program uses std::map instead of Python dictionaries to store move costs). Regardless of whether or not you know path finding, would it be possible for someone to look at my code and tell why it is running so inefficiently?
I ran the visual studios profiler to examine what was so inefficient (I know that queues could be used to speed up searching but keep in mind that this runs x50 times faster in Python with the same code and no priority queue).. It appears that almost all the time is being used by std::map [] operators:
Function Name Total CPU (%) -> 88.01 %
+ std::map<std::pair<int,int>,int,std::less<std::pair<int,int>>,
std::allocator<std::pair<std::pair<int,int> const ,int> > >::
operator[]
My code:
void findPath(pair<int, int> startLocation, pair<int, int> endLocation){
vector<pair<int, int>> openSet;
vector<pair<int, int>> closedSet;
openSet.push_back(startLocation);
map<pair<int, int>, pair<int, int>> cameFrom;
map<pair<int, int>, int> gCosts;
map<pair<int, int>, int> fCosts;
gCosts[startLocation] = 0;
fCosts[startLocation] = heuristic(startLocation, endLocation);
pair<int, int> currentNode;
while (openSet.size() > 0){
currentNode = openSet[0];
for (std::vector<pair<int, int>>::iterator it = openSet.begin(); it != openSet.end(); ++it){
pair<int, int> node = *it;
if (fCosts[node] < fCosts[currentNode])
currentNode = node;
}
if (DEBUG){
cout << "Current Node: " << currentNode.first << " " << currentNode.second << endl;
}
if (currentNode == endLocation){
break;
}
openSet.erase( remove(openSet.begin(), openSet.end(), currentNode), openSet.end() );
closedSet.push_back(currentNode);
vector<pair<int, int>> neighbors = getNeighbors(currentNode);
for (std::vector<pair<int, int>>::iterator it = neighbors.begin(); it != neighbors.end(); ++it){
pair<int, int> neighbor = *it;
if (std::find(closedSet.begin(), closedSet.end(), neighbor) != closedSet.end()) {
continue;
}
int possiblegCost = gCosts[currentNode] + heuristic(currentNode, neighbor);
bool inOpenSet = find(openSet.begin(), openSet.end(), neighbor) != openSet.end();
if (!inOpenSet || (possiblegCost < gCosts[neighbor])) {
cameFrom[neighbor] = currentNode;
gCosts[neighbor] = possiblegCost;
fCosts[neighbor] = possiblegCost + heuristic(neighbor, endLocation);
/*if (DEBUG){
console() << "Modifying neighbor: " << neighbor.first << "," << neighbor.second << " Costs of: "
<< gCosts[neighbor] << " " << fCosts[neighbor] << endl;
}*/
if (!inOpenSet){
openSet.push_back(neighbor);
}
}
}
}
}