24

私はPythonで作業しており、次のコード状況を設定しました:

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

部分関数の呼び出しに時間がかかるのはなぜですか? 部分関数はパラメーターを元の関数に転送しているだけですか、それとも静的引数を全体にマッピングしていますか? また、関数 i のように、すべてのパラメーターが事前定義されている場合、Python には関数の本体を返す関数がありますか?

4

2 に答える 2

26

部分関数の呼び出しに時間がかかるのはなぜですか?

のコードpartialは、関数呼び出しが追加されるため、約 2 倍の時間がかかります。関数呼び出しは高価です:

特に組み込み関数の実行速度と比較すると、Python の関数呼び出しのオーバーヘッドは比較的高くなります。

-

部分関数はパラメーターを元の関数に転送しているだけですか、それとも静的引数を全体にマッピングしていますか?

私の知る限り-はい、引数を元の関数に転送するだけです。

-

また、関数 i のように、すべてのパラメーターが事前定義されている場合、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
于 2013-06-30T09:31:13.813 に答える