49

Python モジュールのインポートを高速化する方法に関する質問は、以前に尋ねられました (Python "インポート" ローダーPython の高速化 -- インポートを高速化しますか? ) が、具体的な例がなく、受け入れられた解決策が得られていません。そのため、ここでもう一度問題を取り上げますが、今回は具体的な例を挙げて説明します。

ディスクから 3D 画像スタックをロードし、それを滑らかにし、ムービーとして表示する Python スクリプトがあります。データをすばやく表示したい場合は、システム コマンド プロンプトからこのスクリプトを呼び出します。これは MATLAB に匹敵するので、データを平滑化するのにかかる 700 ミリ秒で問題ありません。ただし、モジュールのインポートにはさらに 650 ミリ秒かかります。したがって、ユーザーの観点からは、Python コードは半分の速度で実行されます。

これは私がインポートしている一連のモジュールです:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os

もちろん、すべてのモジュールが同じようにインポートに時間がかかるわけではありません。主な犯人は次のとおりです。

matplotlib.pyplot   [300ms]
numpy               [110ms]
scipy.signal        [200ms]

を使用して実験しましfromたが、これは高速ではありません。Matplotlib が主な原因であり、画面の更新が遅いという評判があるため、代替手段を探しました。1 つは PyQtGraph ですが、インポートに 550 ミリ秒かかります。

システムのコマンド プロンプトではなく、対話型の Python セッションから関数を呼び出すという明らかな解決策を 1 つ知っています。これは問題ありませんが、MATLAB に似すぎているため、システム プロンプトから関数を使用できるようにすることを好みます。

私はPythonが初めてで、この時点でどのように進めればよいかわかりません。私は新しいので、提案されたソリューションを実装する方法に関するリンクをいただければ幸いです。理想的には、複数の Mac および Linux マシン間でコードを移植できる必要があるため、単純なソリューションを探しています (私たち全員ではありません!)。

4

5 に答える 5

23

単純なサーバー/クライアントを構築できます。サーバーは継続的に実行され、プロットを作成および更新し、クライアントは処理する次のファイルを通信するだけです。

socketモジュール ドキュメントの基本的な例に基づいて、単純なサーバー/クライアントの例を作成しました: http://docs.python.org/2/library/socket.html#example

ここにserver.pyがあります:

# expensive imports
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while 1:
    conn, addr = s.accept()
    print 'Connected by', addr
    data = conn.recv(1024)
    if not data: break
    conn.sendall("PLOTTING:" + data)
    # update plot
    conn.close()

および client.py:

# Echo client program
import socket
import sys

HOST = ''    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(sys.argv[1])
data = s.recv(1024)
s.close()
print 'Received', repr(data)

サーバーを実行するだけです:

python server.py

これはインポートを行い、クライアントはプロットする新しいファイルのファイル名をソケット経由で送信するだけです:

python client.py mytextfile.txt

次に、サーバーがプロットを更新します。

私のマシンでは、インポートを実行するのに 0.6 秒かかりますが、実行にはclient.py0.03 秒かかります。

于 2013-05-08T00:45:13.833 に答える
8

を使用して、代わりにモジュールを手動でインポートできますimp。こちらのドキュメントを参照してください。

たとえば、import numpy as npおそらく次のように記述できます

import imp
np = imp.load_module("numpy",None,"/usr/lib/python2.7/dist-packages/numpy",('','',5))

これにより、Python が全体を参照sys.pathして目的のパッケージを見つける必要がなくなります。

以下も参照してください。

gtk の手動インポートが失敗する: モジュールが見つからない

于 2016-03-20T22:33:07.323 に答える
2

1.35 秒は長くはありませんが、「クイック チェック」のためにその半分に慣れている場合は、おそらくそう思われると思います。

Andrea は単純なクライアント/サーバーのセットアップを提案していますが、スクリプトをわずかに変更するだけで、作業中にコンソール ウィンドウを開いたままにしておくことも簡単にできるように思えます。

  • スクリプトを呼び出します。スクリプトはインポートを行い、入力を待ちます
  • コンソール ウィンドウを最小化し、作業に切り替えます。
  • コンソールをもう一度選択します
  • スクリプトに何らかの入力を提供する
  • インポートのオーバーヘッドなしで結果を受け取る
  • 喜んで入力を待っている間、スクリプトから再び切り替えます

スクリプトは毎回同じだと思います。つまり、画像スタックの場所や特定のコマンドを毎回指定する必要はありません (ただし、これらも簡単に実行できます!)。

例 RAAC's_Script.py:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os

print('********* RAAC\'s Script Now Running *********')

while True: # Loops forever
    # Display a message and wait for user to enter text followed by enter key.
    # In this case, we're not expecting any text at all and if there is any it's ignored
    input('Press Enter to test image stack...')

    '''
    *
    *
    **RAAC's Code Goes Here** (Make sure it's indented/inside the while loop!)
    *
    *
    '''

スクリプトを終了するには、コンソール ウィンドウを閉じるか、ctrl+c を押します。

私はこれを可能な限りシンプルにしましたが、適切に終了したり、入力に基づいてわずかに異なることを行ったりするなどの処理に必要な余分なものはほとんどありません.

于 2014-08-28T10:51:07.710 に答える