如何以多线程的方式将Python Dict转换为JSON

时间:2012-04-20 18:36:51

标签: python json

我有许多大文件,其中包含数千行python dict格式的行。我正在用json.dump将它们转换成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()

我不太明白Pool在哪里发挥作用,你能解释一下吗?

2 个答案:

答案 0 :(得分:1)

我不知道从多线程获得加速的简单方法,但如果你想要任何加速,那么我建议你尝试使用ujson包而不是{{1} }。它为我带来了非常显着的加速,基本上是免费的。使用方法与使用常规json包的方式相同。

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

答案 1 :(得分:1)

将上面的代码包装在一个函数中,该函数将单个参数作为文件名并将json写入输出文件。

然后从Pool模块创建一个multiprocessing对象,并使用Pool.map()将您的函数并行应用于所有文件列表。这将自动使用CPU上的所有内核,并且因为它使用多个进程而不是线程,所以不会遇到全局解释器锁。

修改:更改程序的主要部分;

  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()