Petr Sulla sent me mail with some improvements to my A* code[1]. I was going to merge his changes into my code, but then realized that I don’t actually use the code anymore (because I’m not working on games at the moment), and I shouldn’t write the code without adequately testing it. So instead I’m posting his notes here. He writes:
In my case it is pretty expensive to calculate the cost and the heuristics (especially the cost). I just doubled the code and calculate the two when they are really needed. This speeded up things from 13 ms to 9 ms (on a 400 MHz PII, 120x120 map, in Delphi) (only the main loop measured)
// remove from here // int k = heuristic.kost(map, N.h, d, hn); // Node N2; // N2.h = hn; // N2.gval = N.gval + k; // N2.hval = heuristic.dist( map, hn, B ); // If this spot (hn) hasn't been visited, its mark is DirNone if( mark.data[hn.m][hn.n].direction == DirNone ) { // insert here int k = heuristic.kost(map, N.h, d, hn); Node N2; N2.h = hn; N2.gval = N.gval + k; N2.hval = heuristic.dist( map, hn, B ); // The space is not marked mark.data[hn.m][hn.n].direction = ReverseDirection(d); mark.data[hn.m][hn.n].f = N2.gval+N2.hval; mark.data[hn.m][hn.n].g = N2.gval; open.push_back( N2 ); push_heap( open.begin(), open.end(), comp ); stats.nodes_added++; } else { // We know it's in OPEN or CLOSED... if( in_open(hn) ) { // and also here int k = heuristic.kost(map, N.h, d, hn); Node N2; N2.h = hn; N2.gval = N.gval + k; N2.hval = heuristic.dist( map, hn, B ); // It's in OPEN, so figure out whether g is better if( N2.gval < mark.data[hn.m][hn.n].g ) { // Search for hn in open
it’s pretty bad going through the whole priority queue all the time in find_in_open - the algorithm spends there close to 1/4 of time. I implemented the PQ myself, so I added a variable index_in_PQ to the marking array and I update it when reorganizing the heap-based PQ. So my find_in_open is just one access to the marking array, although the reorganizing got a bit slower. Speed improvement from 21 ms to 17 ms (which is now the average time for 1 path on my PII/400 on a 120x120 hexes map)