web-dev-qa-db-ja.com

Pythonスクリプトのメモリ使用量を減らす方法

非常に大きなpythonスクリプト、200Kですが、できる限り少ないメモリを使用したいと思います。次のようになります。

# a lot of data structures
r = [34, 78, 43, 12, 99]

# a lot of functions that I use all the time
def func1(Word):
    return len(Word) + 2

# a lot of functions that I rarely use
def func1(Word):
    return len(Word) + 2


# my main loop
while 1:
   # lots of code
   # calls functions

あまり使用しない関数をモジュールに入れ、必要な場合にのみ動的にインポートすると、データにアクセスできなくなります。それは私が得た限りです。

私はPythonが初めてです。

誰かが私を正しい道に連れて行くことができますか?この大きなスクリプトを分割して、メモリ使用量を減らすにはどうすればよいですか?めったに使用されないコードをモジュールに入れて、必要なときにのみそれらを呼び出す価値はありますか?

24
Coo Jinx

構成:

あなたのpythonスクリプトは確かに巨大であるように思われます。おそらく、最初にコードを再編成して、いくつかの モジュールまたはパッケージ に分割することを検討する必要があります。これにより、おそらくコードがより簡単になります。プロファイリングと最適化タスク。

あなたはそこを見てみたいかもしれません:

そしておそらく:

最適化:

コードを最適化するためにできることはたくさんあります...

たとえば、データ構造について...リストまたはリスト内包表記を多用する場合、リストが本当に必要な場所と、タプルや「揮発性」オブジェクト、「遅延」コンテナ、ジェネレータ式など。

見る:

これらのページでは、いくつかの役立つ情報とヒントを見つけることができます。

また、物事を行う方法を研究し、それをあまり貪欲に行う方法がないかどうかを疑問に思う必要があります。Pythonで行う方が良い方法です( tag Pythonic )...これは特にPythonに当てはまります。Pythonでは、多くの場合、1つの「明白な」方法(および1つだけ)があるためです。 Pythonicと言われている他のものよりも優れていることを行う( Zen of Python を参照)。これは、あなたのコードだけでなく、何よりも-パフォーマンスにも影響します。多くの言語とは異なり、何かを行うには多くの方法があるはずだという考えを促進しますPythonは、最高のしたがって、何かを行うには多くの方法がありますが、多くの場合、本当にの方が優れています。

Pythonicalityはあなたのためにアルゴリズムを調整しないので、今、あなたはあなたが物事を行うための最良の方法を使用しているかどうかも確認するべきです。

しかし、最後に、それはあなたのコードに非常に依存しているので、それを見ずに答えることは困難です。

また、 eumiro および Amr によるコメントを必ず考慮してください。

36
cedbeu

このビデオはあなたにいくつかの良いアイデアを与えるかもしれません: http://pyvideo.org/video/451/pycon-2011---quot-dude--where--39-s-my-ram--quot-

4
Bryce

ジェネレータ式とモジュールの利用に関するアドバイスは良いです。時期尚早な最適化は問題を引き起こしますが、コードを書くために座る前に、常に設計について数分費やす必要があります。特に、そのコードが再利用されることを意図している場合。

ちなみに、スクリプトの先頭で多くのデータ構造が定義されていることをおっしゃっています。つまり、それらはすべて最初からメモリに読み込まれているということです。これが非常に大きなデータセットである場合は、特定のデータセットを個別のファイルに移動し、必要な場合にのみロードすることを検討してください。 (csvモジュール、またはnumpy.loadtxt()などを使用)

少ないメモリを使用するのとは別に、メモリをより効率的に使用する方法も検討してください。たとえば、数値データの大きなセットの場合、numpy配列は、計算のパフォーマンスを向上させる情報を格納する方法です。 http://wiki.python.org/moin/PythonSpeed/PerformanceTips に少し日付の古いアドバイスがあります

3
abought

関数を移動しても、メモリ使用量は変わりません。他のモジュールをインポートするとすぐに、モジュール内のすべての関数が定義されます。しかし、関数は多くのメモリを消費しません。それらは非常に反復的ですか?おそらく、関数をリファクタリングすることでコードを減らすことができますか?

@eumiroの質問は正しいです。スクリプトでメモリを使いすぎていませんか?それはどのくらいのメモリを使用し、なぜそれが多すぎるのですか?

2
Ned Batchelder

OOPを利用していて、いくつかのオブジェクトがある場合、

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

次のコードを入力することで、オブジェクトが消費するメモリを減らすことができます。

__slots__ = ("lorem", "ipsum")

次に示すように、__init__関数の直前

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

もちろん、「時期尚早な最適化はすべての悪の根源です」。また、追加の前後にmemの使用状況をプロファイルして、実際に何が行われるかを確認します。これが機能しなくなる可能性があることを理解して、コードを(衝撃的に)破壊することに注意してください。

0