0

The higher-order function functools.partial() can create a new function as follows:

newf(arg1) = functools.partial( f, arg1, val )

which is obviously equivalent to just saying

def newf(arg1): return f( arg1, val )

in terms of what they do. But what about performance? Does functools.partial() actually create a new function that does not need to call f or are they identical?

davidism
  • 121,510
  • 29
  • 395
  • 339
  • 1
    A quick Google search reveals a number of similar or duplicate questions. This is the [top result](http://stackoverflow.com/questions/17388438/python-functools-partial-efficiency). It might help if you used a more specific title, too; you're specifically concerned with performance, not just something 'about' it. – Christian Conkle Oct 07 '14 at 01:38

3 Answers3

2
> import functools
> def nop():
...:     pass
...: 

> %timeit nop()
10000000 loops, best of 3: 63.5 ns per loop

> %timeit functools.partial(nop)()
1000000 loops, best of 3: 205 ns per loop

So I would say it looks pretty trivial unless you are doing something silly. And we can get most of that back if we're going to be calling the partial multiple times:

> f = functools.partial(nop)
> %timeit f()
10000000 loops, best of 3: 86.7 ns per loop
U2EF1
  • 12,907
  • 3
  • 35
  • 37
  • I agree with this answer.. I can not think of a reason that `partial` would be expensive. So go for it ;) – brunsgaard Oct 07 '14 at 01:51
  • I guess what I'm really trying to ask is if the two functions are completely identical, or if there is some difference in the way they are executed. –  Oct 07 '14 at 01:52
1

This is the source code of functools.partial in python 3.4:

def partial(func, *args, **keywords):
    """New function with partial application of the given arguments
    and keywords.
    """
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

try:
    from _functools import partial
except ImportError:
    pass

on the top it defines a purely python fall-back version, and on the bottom it tries to import the C version. You can find the C code here.

behzad.nouri
  • 74,723
  • 18
  • 126
  • 124
0

Here is the current implementation of partial.

Do you understand it? Else ask, but i found it very hard to explain cleanly because of all the inner and outer functions.

def partial(func, *args, **keywords):
    """New function with partial application of the given arguments
    and keywords.
    """
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
brunsgaard
  • 5,066
  • 2
  • 16
  • 15