2016-05-13 3 views
1

私はPythonモジュール(swood)を作成しました。最近まで、多くのクラスを持つ1つの大きなファイルでした。関連するクラスを別々のファイルにリファクタリングした後も、すべてが動作しますが、約50%遅くなります。私は、Pythonが各ファイルのバイトコードをより効率的にキャッシュできるので、起動時間を改善できるので、少し速くなると思っていました。なぜ私のモジュールを複数のファイルに分けるのが遅くなるのですか?

私はこのコードをCPythonで実行しています(PyPyとそのilkでテストされていません)。私は古いバージョンとリファクタリングされたバージョンでline_profilerを実行しました。そして、各ラインで費やされる処理時間の割合は、リファクタの前後でほぼ同じに見えます。ここで

はそれとは何かを持っているかもしれない私のプログラムについてのいくつかのものがあります:

  • これは以前に問題ではありませんでしたがそれは、Noteこれらは高価であるかもしれないインスタンス化するような小さなクラスの多くを作りますリファクタリング。
  • これらのクラスを作成するときは、最初にimportを別のファイルから取得します。
  • 最長かかる部分( scalingmixingオーディオ)
  • で起こっnumpyベースの配列操作がたくさんある
  • 私は彼らが回以上を使用している場合、私は、中にスケールノートを保存するキャッシュを持っています7.5秒。 (code

私のコードは何もせずに複数のファイルに分けた後に遅くなる原因は何ですか?

+1

あなたはおそらく、いくつかの点でめちゃめちゃ:元のループは を置き換えることができます。コードをより多くのモジュールに分けると、すべてのモジュールを読み込むのに少し時間がかかることになりますが、その減速は報告するものよりずっと少なくなります。明らかに一見遅くなって私に飛びついたことはありませんでしたが、あなたのコードにバグがないと思われる奇妙なもの( '__hash__'のような' __eq__'など)がありました。 – user2357112

答えて

2

もう少しベンチマークした後、それは私が疑ったことの1つでした。別のモジュールから関数/クラスにアクセスすると、Pythonインタプリタの別のルックアップが意味され、タイトループで少し減速しました。ドットを回避The Python wiki has something about this, too:

...

は、マップやリストの内包表記を使用することはできませんと仮定? forループで が貼り付けられている可能性があります。 forループの例には別の非効率性があります。 newlist.appendとword.upperはともに、ループを介して毎回 を再評価した関数参照です。

upper = str.upper 
newlist = [] 
append = newlist.append 
for word in oldlist: 
    append(upper(word)) 
2

あなたのリファクタリングは、単にクラスを別のファイルに移動するだけではないようです。例えば、UncachedWavFile__setitem__の方法を失った。そして、他の場所では魔法の数字が変更されています。私はあなたが最初にスローダウンのために他の場所を見ることをお勧めします。

コードベースを別々のファイルにリファクタリングしても、スピードの違いは見られません。起動時間がわずかに短縮されることが予想されます。分割前に分岐を行い、文字通りコードを別々のファイルに分割し、コードのパフォーマンスをプロファイリングしてから、分割してから追加したコードをゆっくりと追加して、毎回コードの速度が低下していることを確認することをおすすめします。

関連する問題