2015-10-07 4 views
13

私はPythonで1/3のような定数計算された浮動小数点値を使用する関数を持っているとします。定数計算はPythonでキャッシュされていますか?

def div_by_3(x): 
    return x * (1/3) 

私がこの関数を繰り返し呼び出すと、1/3の値は効率的に自動的にキャッシュされますか?あるいは次のような手作業をしなくてはなりませんか?

def div_by_3(x, _ONE_THIRD=1/3): 
    return x * _ONE_THIRD 
+1

後者は定数をモジュールレベルのグローバル変数として保持することはできますが(パラメータとして渡す場合を除き)、関数に渡す代わりに定数を保持することもできます。 – Alexander

+0

私はそれをパラメータとして実行するほうが速いと思う(グローバル名を探すのを避ける)。 – aiai

+0

Nope。速度に差はなく、関数でない場合は関数のユーザーにとってあまり明確ではありません。 – Alexander

答えて

12

自分で見つけてください! disモジュールは、原料のこの種を検査するための素晴らしいです:あなたが見ることができるように

>>> from dis import dis 
>>> def div_by_3(x): 
...  return x * (1/3.) 
... 
>>> dis(div_by_3) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    1 (1) 
       6 LOAD_CONST    2 (3.0) 
       9 BINARY_DIVIDE  
      10 BINARY_MULTIPLY  
      11 RETURN_VALUE   

1/3計算が毎回発生します。 (注:私は33.に変更してフロートの除算を強制しました。それ以外の場合は0になります。実際に振る舞いを変更した将来の除算を有効にすることもできます。

そして、あなたの第二のアプローチ:第二の

>>> def db3(x, _ONE_THIRD=1/3.): 
... return x * _ONE_THIRD 
... 
>>> dis(db3) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_FAST    1 (_ONE_THIRD) 
       6 BINARY_MULTIPLY  
       7 RETURN_VALUE   

詳しい情報は、関数オブジェクトをINGのinspectことによって見つけることができます:

>>> inspect.getargspec(db3) 
ArgSpec(args=['x', '_ONE_THIRD'], varargs=None, keywords=None, defaults=(0.3333333333333333,)) 

あなたはデフォルト値がそこにキャッシュされて見ることができます。 //

>>> dis.dis(div_by_3) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    3 (0.3333333333333333) 
       6 BINARY_MULTIPLY 
       7 RETURN_VALUE 

が分裂を整数に切り替える: - :

EDITは(あなたがfrom __future__ import divisionを有効にすると、さらにPythonの2.7で)はPython 3に、彼らはキャッシュされたのですか、これはもう少し面白いです判明します)は、Python 3または2.7 with-future-divisionでこれを変更しないで、0.333..の代わりに0になるように定数を変更するだけです。また、 future divisionを持たない2.7 で整数除算を直接使用すると、0をよく

今日新しいことを学んだ!

+0

どのように2番目のアプローチを説明できますか?部門はどこですか? –

+0

関数が呼び出されるたびにキーワード引数のデフォルト値が計算されますか? – Monkpit

+0

@Monkeyいいえ。デフォルト値は一度(関数定義で)計算され、作成された関数オブジェクトに格納されます。 – tzaman

関連する問題