長時間実行データ処理Pythonスクリプトのプログラム構造
-
05-10-2019 - |
質問
現在の仕事では、CPU を大量に使用するデータ処理を実行する、長時間実行される (数時間から数日かかる) スクリプトを作成しています。プログラム フローは非常に単純です。メイン ループに進み、メイン ループを完了し、出力を保存して終了します。私のプログラムの基本構造は次のようになります。
<import statements>
<constant declarations>
<misc function declarations>
def main():
for blah in blahs():
<lots of local variables>
<lots of tightly coupled computation>
for something in somethings():
<lots more local variables>
<lots more computation>
<etc., etc.>
<save results>
if __name__ == "__main__":
main()
これはすぐに管理できなくなるため、より管理しやすいものにリファクタリングしたいと考えています。実行速度を犠牲にすることなく、これをより保守しやすくしたいと考えています。
ただし、コードの各部分は多数の変数に依存しているため、計算の一部を関数にリファクタリングすると、パラメーター リストが急速に増大して手に負えなくなります。この種のコードをPythonクラスに入れて、ローカル変数をクラス変数に変更する必要がありますか?クラスは決して再利用されず、インスタンスごとに 1 つのインスタンスしか作成されないため、プログラムをクラスに変換することは概念的にはあまり意味がありません。
この種のプログラムのベストプラクティス構造は何ですか?私はPythonを使用していますが、最新のオブジェクト指向言語の機能を前提として、質問は比較的言語に依存しません。
解決
まず、プログラムが数時間または数日間実行される場合、すべてを巨大なメインに置く代わりにクラス/メソッドの使用に切り替えるオーバーヘッドはほとんど存在しません。
さらに、リファクタリングは (多くの変数を渡す必要がある場合でも) 長期的には速度の向上に役立つはずです。適切に設計されたアプリケーションのプロファイリングは、遅い部分を特定してそこを最適化できるため、はるかに簡単になります。もしかしたら、あなたの計算に高度に最適化された新しいライブラリが登場するかもしれません...適切に設計されたプログラムを使用すれば、プラグインしてすぐにテストできます。あるいは、計算のサブセットの速度を向上させるために C モジュール拡張機能を作成することにした場合も、適切に設計されたアプリケーションを使用すると、それも簡単になります。
実物を見ないと具体的なアドバイスは難しい <lots of tightly coupled computation>
そして <lots more computation>
. 。しかし、私はすべてを作ることから始めます for
独自のメソッドをブロックして、そこから先に進みます。
他のヒント
きれいではありませんが、小さなプロジェクトではうまく機能します...
モジュールがSingletonインスタンスであるかのように使用を開始し、モジュールの複雑さや計算が正当化されると感じた場合にのみ、実際のクラスを作成できます。
それを行う場合、「モジュールからインポートされたものから」ではなく「インポートモジュール」を使用することをお勧めします。クリーナーで、「スタッフ」を再割り当てすることができればうまく機能します。また、Googleガイドラインで推奨されています。
クラス(またはクラス)を使用すると、コードを整理するのに役立ちます。フォームのシンプルさ(クラス属性やメソッドの使用など)は、アルゴリズムを見るのに役立ち、パーツをより簡単にテストするのに役立つため重要です。
IMO、これらの利点は、OOPを使用することに伴う可能性のある速度のわずかな損失をはるかに上回ります。