-1

この質問は、主にメモリ内の膨大なデータセットの並べ替えに関して、私がここで尋ねた他の質問に関連しています。

基本的に、これは私が欲しい/持っているものです:

ねじれた XMLRPC サーバーが実行されています。このサーバーは、Foo クラスのいくつか (32) のインスタンスをメモリに保持します。各 Foo クラスには、リスト バー (数百万のレコードが含まれます) が含まれます。データベースからデータを取得し、それを XMLRPC サーバーに渡すサービスがあります。データは基本的に、各 Foo インスタンスに対応するキーを持つ辞書であり、値は次のような辞書のリストです。

data = {'foo1':[{'k1':'v1', 'k2':'v2'}, {'k1':'v1', 'k2':'v2'}], 'foo2':...}

次に、各 Foo インスタンスにそのキーに対応する値が渡され、Foo.bar 辞書が更新されて並べ替えられます。

class XMLRPCController(xmlrpc.XMLRPC):

    def __init__(self):
        ...
        self.foos = {'foo1':Foo(), 'foo2':Foo(), 'foo3':Foo()}
        ...

    def update(self, data):
        for k, v in data:
            threads.deferToThread(self.foos[k].processData, v)

    def getData(self, fookey):
        # return first 10 records of specified Foo.bar
        return self.foos[fookey].bar[0:10]

class Foo():

    def __init__(self):
        bar = []

    def processData(self, new_bar_data):
        for record in new_bar_data:
            # do processing, and add record, then sort
            # BUNCH OF PROCESSING CODE
            self.bar.sort(reverse=True)

問題は、更新関数が多数のレコード (たとえば 100K +) を使用して XMLRPCController で呼び出されると、32 個の Foo インスタンスすべてが process_data メソッドを完了するまで getData 呼び出しに応答しなくなることです。deferToThread が動作すると思っていましたが、どこに問題があるのか​​を誤解していると思います。

任意の提案...この必要な動作をサポートしている場合、Cherrypy など、他のものを使用することにオープンです。


編集

@Troy: これが原子炉のセットアップ方法です

reactor.listenTCP(port_no, server.Site(XMLRPCController)
reactor.run()

GIL に関する限り、sys.setcheckinterval() の値を小さい値に変更して、データのロックを解除して読み取りできるようにすることは実行可能なオプションでしょうか?

4

2 に答える 2

1

アプリの応答性を高める最も簡単な方法は、CPUを集中的に使用する処理を小さなチャンクに分割し、その間にツイストリアクターを実行させることです。たとえば、reactor.callLater(0、process_next_chunk)を呼び出して、次のチャンクに進みます。自分で協調マルチタスクを効果的に実行します。

別の方法は、別々のプロセスを使用して作業を行うことです。そうすれば、複数のコアの恩恵を受けることができます。Ampouleを見てください:https : //launchpad.net/ampouledeferToThreadに似たAPIを提供します。

于 2010-02-04T20:23:33.027 に答える
0

processData メソッドが実行される時間も、ねじれたリアクターをどのようにセットアップしているかもわかりません。 デフォルトでは、ツイスト リアクターには 0 ~ 10 スレッドのスレッド プールがあります。32 もの長時間実行計算を 10 スレッドに延期しようとしている可能性があります。これは準最適です。

また、これらすべてのコレクションを更新する際に GIL が果たしている役割についても尋ねる必要があります。

編集: プログラムに重大な変更を加える前に ( を呼び出すなどsys.setcheckinterval())、おそらくプロファイラーまたは python trace モジュールを使用して実行する必要があります。これらは、常にどのメソッドが使用されているかを示しているはずです。適切な情報がなければ、適切な変更を行うことはできません。

于 2010-02-04T19:06:51.283 に答える