I’m a big fan of functools.partial myself. It allows you to take a function, preset some of its arguments and return another function which you can call with more arguments. Not sure if currying is the right term here, but I’ve heard people refer to functools.partial like that.
Today while browsing the source code for the futures module I came across this class:
The moment I saw that func, args and kwargs were saved as attributes in the instance I thought: “why not use partial and save a single attribute?”. Then I thought that maybe performance had something to do here, so I wrote a
dead simple stupid test to check it out:
Here are the results using CPython 2.7.3:
In : %timeit testpartial.do_test(testpartial.WorkItem) 100000 loops, best of 3: 5.26 us per loop In : %timeit testpartial.do_test(testpartial.WorkItemPartial) 100000 loops, best of 3: 2.65 us per loop
We are talking microseconds here, but still the version with partial is almost twice as fast.
Now, lets see how PyPy performs:
In : %timeit -n 10000 testpartial.do_test(testpartial.WorkItem) 10000 loops, best of 3: 154 ns per loop Compiler time: 554050.78 s In : %timeit -n 10000 testpartial.do_test(testpartial.WorkItemPartial) 10000 loops, best of 3: 2.49 us per loop
Fun, the version without partial goes into the nanoseconds! And the one with partial doesn’t improve much with regards to CPython. Interesting.
So what’s the take here? Well, whenever I see fit I use partial, code looks nicer and it’s apparently faster, so why not? 🙂