我一直在尝试将包含多行(270亿)的大型文件转换为JSON。 Google Compute建议我利用多线程来改善写入时间。我已将此代码转换为:
import json
import progressbar
f = open('output.txt', 'r')
r = open('json.txt', 'w')
import math
num_permutations = (math.factorial(124)/math.factorial((124-5)))
main_bar = progressbar.ProgressBar(maxval=num_permutations, \
widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage(), progressbar.AdaptiveETA()])
main_bar.start()
m = 0
for lines in f:
x = lines[:-1].split(' ')
x = json.dumps(x)
x += '\n'
r.write(x)
m += 1
main_bar.update(m)
到此:
import json
import progressbar
from Queue import Queue
import threading
q = Queue(maxsize=5)
def worker():
while True:
task = q.get()
r.write(task)
q.task_done()
for i in range(4):
t = threading.Thread(target=worker)
t.daemon = True
t.start()
f = open('output.txt', 'r')
r = open('teams.txt', 'w')
import math
num_permutations = (math.factorial(124)/math.factorial((124-5)))
main_bar = progressbar.ProgressBar(maxval=num_permutations, \
widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage(), progressbar.AdaptiveETA()])
main_bar.start()
m = 0
for lines in f:
x = lines[:-1].split(' ')
x = json.dumps(x)
x += '\n'
q.put(x)
m += 1
main_bar.update(m)
我已经从模块手册中直接复制了Queue编码。
之前,整个脚本需要2天。现在说20天了!我不太清楚为什么,有人可以向我解释这个吗?
编辑:这可以被认为是一个Python全局解释器锁(GIL)问题,但是,我认为不是这样 - 它不是计算密集型的,并且是一个IO瓶颈问题,来自线程文档:
如果您希望您的应用程序更好地利用计算 多核机器的资源,建议你使用 多。但是,线程仍然是一个合适的模型 您希望同时运行多个I / O绑定任务。
我对此的理解是有限的,但我相信这是后者,即。 IO绑定任务。这是我最初的想法,当我想首先进行多线程时:计算被IO调用阻止,可以将其放到一个单独的线程中以允许计算功能继续。
进一步编辑:也许事实是我从INPUT获得了一个IO块,这就是减慢它的速度。关于如何有效地将'for'循环发送到单独的线程的任何想法?谢谢!
答案 0 :(得分:1)
如果你想加快速度,根本不使用Python - 任务很简单,可以处理Unix过滤器,例如:
sed 's/ /", "/g; s/^/["/; s/$/"]/' output.txt > json.txt
有关其工作原理的说明,请参阅此处:https://stackoverflow.com/a/14427404/4323
如果您关心速度,使用Python的问题在于您从输入文件中一次从根本上读取一行。现在,你可以通过一些奇特的方式进行阅读(分而治之),但如果你只是想加快速度,那么上面应该可以解决问题。
如果你想要一个进度条,请使用pv
(来自许多Linux系统上的软件包moreutils
),我认为这会是这样的:
pv output.txt | sed 's/ /", "/g; s/^/["/; s/$/"]/' > json.txt