我有许多大文件,其中包含数千行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在哪里发挥作用,你能解释一下吗?
答案 0 :(得分:1)
我不知道从多线程获得加速的简单方法,但如果你想要任何加速,那么我建议你尝试使用ujson
包而不是{{1} }。它为我带来了非常显着的加速,基本上是免费的。使用方法与使用常规json
包的方式相同。
答案 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()