首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python函数工具部分效率

Python函数工具部分效率
EN

Stack Overflow用户
提问于 2013-06-30 16:09:21
回答 2查看 5.4K关注 0票数 24

我一直在使用Python,我设置了以下代码情形:

代码语言:javascript
复制
import timeit

setting = """
import functools

def f(a,b,c):
    pass

g = functools.partial(f,c=3)    
h = functools.partial(f,b=5,c=3)   
i = functools.partial(f,a=4,b=5,c=3)
"""

print timeit.timeit('f(4,5,3)', setup = setting, number=100000)
print timeit.timeit('g(4,5)', setup = setting, number=100000)
print timeit.timeit('h(4)', setup = setting, number=100000)
print timeit.timeit('i()', setup = setting, number=100000)

结果是我得到了以下结果:

代码语言:javascript
复制
f: 0.181384086609
g: 0.39066195488
h: 0.425783157349
i: 0.391901016235

为什么对分部函数的调用花费的时间更长?分部函数只是将参数转发给原始函数,还是将静态参数映射到整个函数?另外,如果所有参数都是预定义的,Python中有没有一个函数可以返回填充的函数体,就像函数i一样?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-30 17:31:14

为什么对分部函数的调用花费的时间更长?

由于额外的函数调用,使用partial编写的代码花费的时间大约要长两倍。函数调用are expensive:

中的函数调用开销相对较高,特别是与内置函数的执行速度相比。

-

是分部函数,只是将参数转发给原始函数,还是将静态参数映射到整个函数?

据我所知--是的,它就是forwards the arguments to the original function

-

还有,如果所有的参数都是预定义的,Python语言中有没有一个函数可以返回被填充的函数体,比如

i?

不,我不知道Python中有这样的内置函数。但我认为可以做你想做的事情,因为函数是可以复制和修改的对象。

这是一个原型:

代码语言:javascript
复制
import timeit
import types


# http://stackoverflow.com/questions/6527633/how-can-i-make-a-deepcopy-of-a-function-in-python
def copy_func(f, name=None):
    return types.FunctionType(f.func_code, f.func_globals, name or f.func_name,
        f.func_defaults, f.func_closure)


def f(a, b, c):
    return a + b + c


i = copy_func(f, 'i')
i.func_defaults = (4, 5, 3)


print timeit.timeit('f(4,5,3)', setup = 'from __main__ import f', number=100000)
print timeit.timeit('i()', setup = 'from __main__ import i', number=100000)

这就给出了:

代码语言:javascript
复制
0.0257439613342
0.0221881866455
票数 26
EN

Stack Overflow用户

发布于 2018-05-06 15:37:07

使用部分应用的参数调用函数的开销更大,因为函数调用的数量是原来的两倍。functools.partial()的效果与下面的示例类似:

代码语言:javascript
复制
def apply_one_of_two(f, a):
    def g(b):
        return f(a, b)
    return g

这意味着apply_one_of_two()返回一个函数,当它被调用时,这会导致对原始函数f的额外调用。

由于Python通常不会对此进行优化,因此它直接转化为额外的运行时工作。

但这并不是您的微基准测试中要考虑的唯一因素。您还可以在部分调用中从位置参数切换到关键字参数,这会带来额外的开销。

当您颠倒原始函数中的参数顺序时,您不需要在部分调用中使用关键字参数,然后运行时差异会有所减小,例如:

代码语言:javascript
复制
import timeit

setting = """
import functools

def f(a,b,c):
    pass

g = functools.partial(f, 4)
h = functools.partial(f, 4, 5)
i = functools.partial(f, 4, 5, 3)
"""

print(timeit.timeit('f(4, 5, 3)', setup = setting, number=100000))
print(timeit.timeit('g(5, 3)',    setup = setting, number=100000))
print(timeit.timeit('h(3)',       setup = setting, number=100000))
print(timeit.timeit('i()',        setup = setting, number=100000))

输出(在Fedora 27/Python3.6下的英特尔Skylake i7上):

代码语言:javascript
复制
0.010069019044749439
0.01681053702486679
0.018060395028442144
0.011366961000021547
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17388438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档