2009-07-04 8 views
7

私はGoogle App Engine環境とPythonでのプログラミングに取り組んでいます。基本的に乱数/文字列を生成してmemcacheに格納する関数を作成しています。1つの大きな処理時間の代わりに別々の関数を作成するのは処理時間が遅いのですか?

def generate_random_string(): 
# return a random 6-digit long string 

def check_and_store_to_memcache(): 
    randomstring = generate_random_string() 
    #check against memcache 
    #if ok, then store key value with another value 
    #if not ok, run generate_random_string() again and check again. 

1つの大きな機能の代わりに2つの機能を作成すると、パフォーマンスに影響しますか?私は2つの方が好きですが、それは私の考え方によくマッチしますが、それが「ベストプラクティス」であれば、それらを組み合わせても構いません。

+0

コードが正しく表示されるように4つのスペースをインデントすることができます。 –

答えて

28

コードを読んで理解しやすくすることに重点を置いています。

これを実行したら、パフォーマンスに問題がある場合は、何が原因かを調べてください。

Pythonが含まれているほとんどの言語は、メソッド呼び出しを行うためのオーバーヘッドがかなり低い傾向があります。このコードを1つの関数に入れることは、パフォーマンスメトリクスを(劇的に)変更することにはなりません。おそらく、乱数生成は、2つの関数を持たない大部分の時間になると思います。

つまり、分割関数はパフォーマンスに(非常にマイナーな)影響を与えます。しかし、私はそれをこのように考えています。それは、高速道路の80mphから79.99mphへとあなたを連れて行くかもしれません。あなたが完全に停止しなければならないので、ストップライトや渋滞を避けるために見守るべき重要なことは...

+0

+1、非常に良いアドバイス。 –

+5

あなたは早すぎる最適化が解決するよりも多くの問題を引き起こすとは言及していませんでした。 –

+0

彼は堅実な車の類推で働いた。スタイル+1! – Eric

4

リードが正しい。あなたが検討している変更については、関数呼び出しのコストは少数のサイクルであり、気付く前に1秒あたり10^8回行う必要があります。

しかし、多くの場合、人々は別の極端に行き、のように、関数呼び出しにはコストがかかるように注意します。私は抽象化のレイヤーがたくさんある過度に設計されたシステムでこれを見てきました。

何が起こるかは、何かが容易に呼び出せれば、速いという人間の心理学があるということです。これは、厳密に必要とされるよりも多くの関数呼び出しを作成することにつながり、複数の抽象レイヤにわたってこの問題が発生した場合、無駄は指数関数的になる可能性があります。

リードの駆動例に続いて、関数呼び出しは迂回のようにすることができ、かつ迂回は迂回路が含まれている場合、それらはまた、迂回路が含まれている場合は、すぐに各機能ので、ノー明らか理由で、浪費されている膨大な時間がありますコールは無邪気に見える。

14

ほとんどの場合、速度を上げる「インライン化」機能は、体重を減らすために髪をカットするようなものです。

+8

++すばらしい比喩! –

2

他の人が言っているように、私はこの特定のシナリオでは心配しません。関数呼び出しに含まれる非常に小さなオーバーヘッドは、各関数の内部で行われる処理と比較して薄くなります。そして、これらの機能がすぐに連続して呼び出されない限り、それはおそらくそれほど重要ではないでしょう。

しかし、良い質問です。場合によっては、コードを複数の機能に分割しないことが最善です。たとえば、ネストされたループを使用して数学的に集中的な作業を行う場合、できるだけ少ない数の関数呼び出しを内側のループで行うことが最善です。これは、単純な数学演算自体が非常に安価であり、その次に関数呼び出しオーバーヘッドが顕著なパフォーマンスの低下を引き起こす可能性があるからです。

私は、VC++アプリケーションで使用していた数学ライブラリのhypotenuse関数が非常に遅いことを発見しました。そのような単純な機能のセット - 返されたsqrt(a * a + b * b) - それはどれくらい難しいので、私にはばかげているようでした。だから私は自分自身を書いて、16倍以上のパフォーマンスを改善しました。次に、関数に "インライン"キーワードを追加し、それを3倍高速化しました(この時点で約50倍速くなりました)。その後、コードを関数から取り出してループ自体に入れ、さらに小さなパフォーマンスの向上を見ました。だから...ええ、それはあなたが違いを見ることができるシナリオのタイプです。

+0

sqrt(a * a + b * b)になりませんか? –

+0

ああ、良いキャッチ。 –

関連する問題