Skip to main content

Benchmarking Dynamic Programming with Python

In this post I'll explore and benchmark some simple dynamic programming concepts in Python.

The example I'll use is a classic recursive implementation of the fibonacci series. (And for simplicity I'll skip the first element in the series (fib(0)=0).)

_DSC7544.jpg

Naive approach 

This implementation:

...works well (enough) for small numbers:

but becomes impossibly slow quickly...

...since it has a time complexity of O(2n). (So our seemingly harmless fib(42) would result in more than 4 trillion calls to fib... (Or about 4 times the number of bacteria on the human body... Or 2 times the number of galaxies in the observable universe... Or more than the estimated population of fish in the ocean... Etc.))

Enter dynamic programming

Since the result of these recursive calls to fib are all deterministic, we can cache the results instead of recalculating them.

@functools.cache

First a test by simply leveraging the cache in the library functools...

This speeds, as expected, the runtime up significantly...

...by a factor of about a million in the case of this 43rd fibonacci number.

(Of course we can't run timeit in loops, as the first run would generate the cache for successive runs...)

Hand made

Then we can to compare this to the classic, hand made, way to implement memoization in dynamic programming, like so:

This should give more or less the same results as above. And it does. 

Interestingly, it actually systematically outperforms the functools@cache slightly on my M1 air.

On my intel desktop I get similar difference in results results:

Conclusion

Leveraging @functools.cache is a great way to implement dynamic programming memoization in Python with little code overhead (but you still might be able to tailor make a faster solution).

Comments

Popular posts from this blog

Using a Raspberry Pi as a MIDI USB/5-pin bridge

In my constant... need... to get everything music instrument related to communicate with each other, I wanted to look into ways to get some of my keyboards/synths with only MIDI over USB to talk to devices with regular good old-fashioned 5-pin MIDI ports from the eighties. Cables! First I had a quick look at off the shelf solutions. The most interesting one being the Kenton MIDI USB Host – providing MIDI host functionality for USB devices as well as regular MIDI in and out in a small box. Unfortunately it is rather expensive (~125 €) and a reliable online source warned me that it was not entirely stable in collaboration with my OP-1, so I started thinking of more... home-grown solutions. I decided to try to use my old Raspberry Pi and see if that would serve as a USB host with a borrowed MIDI USB adapter. (Thanks Simon.) A cheaper, and, as an added boon, a nerdier solution. Step 1: Get the USB MIDI device up and running This was the easy part. The device I have been lent ...

Fix your rapid blinking Marantz SR-6004 using nothing but 3 fingers - and a thumb

A couple of years ago my (most of the time excellent) Maranz SR6004 acted up. It did't want to turn itself on. Properly. Just stood there and blinked rapidly. Its little red light that is. At me. The solution was so simple that I didn't bother to write it down as I was sure to remember it. Alas, no. Some weeks ago it did it again. (Can it be the heat?) Just stood there blinking rapidly at me. The manual just said - as it said last time around - that it was time to return the unit to it's maker. Or similar. Some googling led me to this page:  http://www.allquests.com/question/4056803/Marantz-XXX4-Series-Failure-Issues.html  The technical term for what I had experienced seems to be "The Pop of Death". Aïe. But!, humongous letters said: YOU CAN SOMETIMES RESET THE UNIT BY PRESSING SURR MODE, CLEAR AND EXIT SIMULTANEOUSLY And so I did. And so it was fixed. And all was well. (And now I have written it down for the next time.)

Add overall lesson timing to video listings on Coursera

Marché de La Rochelle HDR  Probably about two years ago - when taking Andrew Ng's excellent "Machine Learning" MOOC, Johannes sent me a piece of JavaScript that populated the video lists with overall time per lesson just by pasting it into the URL-thingy in Chrome. Magic. Today when I sat down to start the course on "General Game Playing" that I have signed up for, but, alas, not (yet) found much time for, I thought of that piece of code and wondered if I, with my new knowledge of JavaScript, could whip up something like that. (Also I couldn't find Johannes' original one.) I quickly hacked together something this afternoon over a flat white in a hipster cafe here in Lyon. And lo and behold it worked. Then I extended the functionality to also show minutes and seconds of unwatched video - as well as total overall counters for the entire course. Now each lesson heading reads "Lesson N - Name [time remaining/total time]" instead of just ...