2016-07-05 5 views
3

私のプログラムの特定のモジュールに対して、インスタンスのリストが返されるかどうかはまったく違いがないことに気づいただけです。固定されたシードでは、結果は同じです。インスタンスのリストを返すことで違いはありませんか?パフォーマンスはどうですか?

したがって、私は知っているしたいと思います:

  1. return文を含める方が良いプログラミングの練習のようです。あれは正しいですか?

  2. 私は主にパフォーマンスが心配です。コンピュータで進行中の他のことが結果に影響を与えているように見えるので、私はそれをタイミングづけするのが難しいです。私は4分3秒を得て、次に1つのカンマを変えずに5分を得る。

は、以下の例を参照してください:

別のモジュールから呼び出されて別のインスタンスを含むリストの多くは、オブジェクトを通過する大きな機能があります:

def check_demographics(month, my_agents, families, firms, my_graveyard, year, mortality_men, mortality_women, fertility, state_id): 

私が持っている機能の中には、次の関数:

def mortal(my_agents, my_graveyard, families, agent, firms): 
    my_agents.remove(agent) 
    my_graveyard.append(agent) 
    families[agent.get_family_id()].death_member(agent) 
    if families[agent.get_family_id()].num_members() == 0: 
     families[agent.get_family_id()].empty_house() 
    if agent.is_employed(): 
     firms[agent.get_workplace()].obit(agent) 
    return my_agents, families, firms, my_graveyard 

上記のケースでは、戻り値がopであることがわかりました。エージェント、ファミリなどを含むリストを返すことに違いはありません。

この例は再現性がありませんが、問題は一般的な事実に関連しています。

私はリストがメモリのどこかにあると仮定しています。

p.s.私はコンピュータ科学者ではなく、エージェントベースのモデリングを試みている研究者です。ありがとう!

+0

あなたの質問は何ですか?リストを返す必要がないのは、すべての操作がインプレース操作であるからです。あなたがあなたのリストにREFERENCEを渡しているので、それらのインプレース操作はリスト自体で行われ、あなたが渡した同じ参照が影響を受けるでしょう。 –

+0

質問は:それがオプションの場合、私はリターンを必要としない、そうですか?第二に、どちらの方法がより早いか(返品の有無にかかわらず)。ありがとう。 –

+1

pythonによって返されるものは、それらのオブジェクトへの参照のタプルです。より多くの参照を介して機能する関数全体のオーバーヘッドと比較すると、それは単純に無視できます。 'return'を持つかどうかは、あなたの関数がするはずの問題です。一般的に、pythonは、これを強調するためにインプレースで変更された入力を返さないようにします。ところで、あなたのコードを*時間にするべきではありません。 – MisterMiyagi

答えて

3

原則として、何も返さない方が高速です。実際には、それは問題ではなく、役に立たないミクロ最適化です。

Pythonはオブジェクトの周りを動かず、の参照を(名前に格納されている)オブジェクトに移動します。 C++のバックグラウンドをお持ちの場合は、return a,b,cは3つのポインタの配列を返すと考えてください。このためのパフォーマンスオーバーヘッドは、関数が実行している他のすべての明示的な操作に比べて無視できるものです。

パフォーマンスが心配な方は、プログラムの時間を決める必要はありません。いずれかのプロファイルあなたのプログラムであなたのプログラムのどこにかなりの時間が費やされたかを確認するには、時間が費やされます。または時間重要なコード(プロファイリングで識別されたもの)をより良くする方法を見つけるためのテストコード。出発点は、タイミングコード用のtimeitパッケージと、vmprofなどのさまざまなpythonプロファイラです。定数をしません

$ python3 -m timeit -s 'def foo():' -s ' pass' 'foo()' 
10000000 loops, best of 3: 0.0994 usec per loop 
$ python3 -m timeit -s 'def foo():' -s ' return' 'foo()' 
10000000 loops, best of 3: 0.0981 usec per loop 
$ python3 -m timeit -s 'def foo():' -s ' return 1, 2' 'foo()' 
10000000 loops, best of 3: 0.0961 usec per loop 
$ python3 -m timeit -s 'bar, foo=object(), object()' -s 'def foo():' -s ' return foo, bar' 'foo()' 
10000000 loops, best of 3: 0.136 usec per loop 

はあなたが(暗黙のNoneを)何も返さない、返さないかどうかを返す:

例えば、一般的にはreturnのオーバーヘッドを見つけるために、あなたはその明確な声明を時間を計ること本当に重要です。実際にオブジェクトを返すと、約0.04usec(!!!)のオーバーヘッドが追加されます。ちょうどを呼び出す機能は既に既に性能のために2.5倍も高価です。

コーディングスタイルの観点から見ると、IMOはPythonの標準ライブラリのビューが最善です。何かがインプレースで変更された場合、それを返さないでください。これは、オブジェクトが副作用によって変更され、新しい参照を作成する必要がないことを示しています。

関連する問題