2013-06-30 23 views
13

我一直使用Python和我建立了下面的代碼情況:Python的functools局部效率

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) 

我得到以下的結果:

f: 0.181384086609 
g: 0.39066195488 
h: 0.425783157349 
i: 0.391901016235 

爲什麼到呼叫部分功能需要更長時間部分函數只是將參數轉發給原始函數,還是它將靜態參數映射到整個函數?還有,Python中是否有函數返回填充的函數體,因爲所有參數都是預定義的,就像函數i一樣?

回答

15

爲什麼對部分函數的調用需要更長的時間?

由於附加的函數調用,partial的代碼需要約兩倍的時間。函數調用are expensive:

Python中的函數調用開銷相對較高,尤其是與內置函數的執行速度相比。

-

只是轉發參數到原來的功能,或者它整個映射靜態參數的部分功能?

據我所知 - 是的,它只是forwards the arguments to the original function

-

而且也有Python中的函數返回一個函數體填充因爲所有的參數都是預定義的,就像我的功能?

不,我不知道Python中的這種內置函數。但我認爲可以做你想做的事情,因爲函數是可以複製和修改的對象。

這裏是一個原型:

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) 

這給:

0.0257439613342 
0.0221881866455 
+0

感謝您的幫助。有沒有可能你或任何人能夠給我提示如何做到這一點?它涉及操縱字節碼對象(函數.__代碼___)還是隻能通過函數對象來完成? – user2515310

+0

我已經更新了我的答案。但你真的關心速度嗎?你怎麼了? – warvariuc

+0

你是絕對驚人的。謝謝。出於利益考慮,我正在研究一個Python API,並希望開發人員能夠在一個元素上定義一個函數,然後將該函數插入到一個快速循環中,但我正在使用的Python實現中的函數調用非常禁止加速(從我的timeit結果中可以看出。 – user2515310