1

Pythondict形式で数千行の大きなファイルがたくさんあります。json.dumpsを使用してそれらをjson文字列に変換しています。

import json
import ast

mydict = open('input', 'r')
output = open('output.json', "a")

for line in mydict:
        line = ast.literal_eval(line)
        line = json.dumps(line)
        output.write(line)
        output.write("\n")

これは問題なく機能しますが、シングルスレッド方式で機能します。システムの残りのコアを利用して処理を高速化する簡単な方法はありますか?

編集:

私がここでマルチプロセッシングライブラリから始めた提案に基づいて:

import os
import json
import ast
from multiprocessing import Process, Pool

mydict = open('twosec.in', 'r')

def info(title):
        print title
        print 'module name:', __name__
        print 'parent process: ', os.getppid()
        print 'process id:', os.getpid()

def converter(name):
        info('converter function')
        output = open('twosec.out', "a")
        for line in mydict:
                line = ast.literal_eval(line)
                line = json.dumps(line)
                output.write(line)
                output.write("\n")

if __name__ == '__main__':
        info('main line')
        p = Process(target=converter, args=(mydict))
        p.start()
        p.join()

プールがどこで登場するのかよくわかりませんが、詳しく説明していただけますか?

4

2 に答える 2

2

マルチスレッドからスピードアップを得る簡単な方法はわかりませんが、何らかのスピードアップが本当に必要な場合は、のujson代わりにパッケージを試すことをお勧めしますjson。それは私にとって非常に重要なスピードアップを、基本的に無料で生み出しました。json通常のパッケージと同じように使用してください。

http://pypi.python.org/pypi/ujson/

于 2012-04-20T18:45:44.880 に答える
1

上記のコードを、単一の引数としてファイル名を取り、jsonを出力ファイルに書き込む関数でラップします。

次に、モジュールPoolからオブジェクトを作成し、を使用して、すべてのファイルのリストと並行して関数を適用します。これにより、CPU上のすべてのコアが自動的に使用され、スレッドの代わりに複数のプロセスが使用されるため、グローバルインタープリターロックに遭遇することはありません。multiprocessingPool.map()

編集:プログラムの主要部分を次のように変更します。

  if __name__ == '__main__':
     files = ['first.in', 'second.in', 'third.in'] # et cetera
     info('main line')
     p = Pool()
     p.map(convertor, files)
     p.close()

もちろんconvertor()、入力名から出力名を派生させるように変更する必要もあります。

以下は、 ImageMagickプログラムを使用してDICOMファイルをPNG形式に変換するプログラムの完全な例です。

"Convert DICOM files to PNG format, remove blank areas."

import os
import sys # voor argv.
import subprocess
from multiprocessing import Pool, Lock

def checkfor(args):
    try:
        subprocess.check_output(args, stderr=subprocess.STDOUT)
    except CalledProcessError:
        print "Required program '{}' not found! exiting.".format(progname)
        sys.exit(1)

def processfile(fname):
    size = '1574x2048'
    args = ['convert', fname, '-units', 'PixelsPerInch', '-density', '300', 
            '-crop', size+'+232+0', '-page', size+'+0+0', fname+'.png']
    rv = subprocess.call(args)
    globallock.acquire()
    if rv != 0:
        print "Error '{}' when processing file '{}'.".format(rv, fname)
    else:
        print "File '{}' processed.".format(fname)
    globallock.release()

## This is the main program ##
if __name__ == '__main__':
    if len(sys.argv) == 1:
        path, binary = os.path.split(sys.argv[0])
        print "Usage: {} [file ...]".format(binary)
        sys.exit(0)
    checkfor('convert')
    globallock = Lock()
    p = Pool()
    p.map(processfile, sys.argv[1:])
    p.close()
于 2012-04-20T19:10:47.400 に答える