Closed jmitchell closed 7 years ago
While testing more mazes I found a minor bug with the new priority queue. Please wait to merge until I've submitted a fix.
This is interesting. I ignored the HeapPQ because I thought didn't didn't have a "decreasekey" function. It seems you've implemented one through a remove + add option. It certainly looks faster, wikipedia suggests that a fibheap is the optimal pq structure, but I strongly suspect that depends on the way it's being used, and also relies on my implementation being optimised, which it probably isn't!
I fixed the bug and profiled more extensively on other inputs. The initial gains I saw on perfect2k.png
apparently don't generalize. There's more context in the latest commit comment. I anticipate more refactoring will lead to performance improvements.
Fibonacci heaps, as I understand it, are theoretically ideal, but not necessarily in practice. Binary heaps, like heapq
's implementation, can represent the tree in a contiguous array of memory, which is better for cache locality. In contrast Fibonacci heaps are less consistently structured, so they necessarily have more layers of indirection. I don't know in this case which approach will prove fastest after optimizations, but I'm really curious!
The latest change is a nice speed improvement for all priority queues. It includes changing to the HeapPQ
implementation. More info in commit message, and latest profiler images below.
profile.py 203.06s user 3.63s system 100% cpu 3:26.50 total
profile.py 130.79s user 2.84s system 100% cpu 2:13.50 total
Also, having thought about it, even if the fib heap decreasekey is very efficient, I'm not actually sure it's called on a perfect maze. There's never an alternative path to a node, so we're never in a situation where it's needed. It's pretty rare even in the braid mazes. A pq that focuses on speed of insert and removemin is likely to be faster.
A priority queue based on Python's
heapq
is significantly faster thanFibHeap
. ThePriorityQueue
abstract class establishes a standard interface used by both implementations, and minimal changes were required toastar.py
anddijkstra.py
to use it.Performance analysis
FibPQ
HeapPQ