2

同じ IP から何度もアクセスされていないかどうかをチェックするこの python cgi スクリプトがあります。すべて問題なければ、大きなファイル形式のディスク (11MB) を読み取り、ダウンロードとして返します。

動作しますが、パフォーマンスは最悪です。ボトルネックは、この巨大なファイルを何度も読み込んでいるようです。

def download_demo():
    """
    Returns the demo file
    """

    file = open(FILENAME, 'r')
    buff = file.read()

    print "Content-Type:application/x-download\nContent-Disposition:attachment;filename=%s\nContent-Length:%s\n\n%s" %    (os.path.split(FILENAME)[-1], len(buff), buff)

どうすればこれをより速くすることができますか? ファイルを保持するために RAM ディスクを使用することを考えましたが、もっと良い解決策があるはずです。mod_wsgicgi スクリプトの代わりに使用すると役立つでしょうか? 大きなファイルをApacheのメモリ空間に保持できますか?

どんな助けでも大歓迎です。

4

4 に答える 4

9

mod_wsgi を使用し、次のようなものを使用します。

def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)

    file = open('/usr/share/dict/words', 'rb')
    return environ['wsgi.file_wrapper'](file)

つまり、WSGI 標準の wsgi.file_wrapper 拡張機能を使用して、Apache/mod_wsgi が sendfile/mmap を使用してファイル コンテンツの最適化された応答を実行できるようにします。つまり、アプリケーションがファイルをメモリに読み込む必要さえありません。

于 2009-09-22T23:53:29.420 に答える
2

なぜあなたはすべてを1つの印刷ステートメントで印刷しているのでしょうか? Python は、コンテンツ ヘッダーを処理するためにいくつかの一時的な文字列を生成する必要があり、その最後の %s のために、ファイルのコンテンツ全体を 2 つの異なる文字列変数に保持する必要があります。これはより良いはずです。

print "Content-Type:application/x-download\nContent-Disposition:attachment;filename=%s\nContent-Length:%s\n\n" %    (os.path.split(FILENAME)[-1], len(buff))
print buff

Python が使用していない一時バッファーを作成しないように、生の IO モジュールを使用してファイルを読み取ることも検討してください。

于 2009-09-22T20:25:07.083 に答える
1

一度にたとえば 16KB のチャンクを読み取って出力 (つまり、バッファリング) してみてください。おそらく、Python はバックグラウンドで何か遅いことを行っており、手動でバッファリングする方が速い可能性があります。

RAM ディスクなどを使用する必要はありません。OS ディスク キャッシュがファイルの内容をキャッシュする必要があります。

于 2009-09-22T20:24:06.867 に答える
1

mod_wsgi または FastCGI は、スクリプトを実行するたびに Python インタープリターをリロードする必要がないという意味で役立ちます。ただし、ファイルの読み取りのパフォーマンスを向上させることはほとんどありません (それが実際のボトルネックである場合)。代わりに memcached に沿ったものを使用することをお勧めします。

于 2009-09-22T20:24:12.353 に答える