Python 列表的多进程字典
Python multiprocess dict of list
我需要用 Python 3.6 在多进程中做一些事情。也就是说,我必须更新一个添加对象列表的字典。由于这些对象是不可拾取的,因此我需要使用 dill
而不是 pickle
和 multiprocess
来自 pathos
而不是 multiprocessing
,但这不应该是问题所在。
将列表添加到字典需要在添加到字典之前重新序列化列表。这会减慢一切,并且花费与没有多处理相同的时间。你能建议我一个解决方法吗?
这是我的 python 3.6 代码:
init1
工作正常但速度慢,init2
速度快但坏了。其余仅供测试。
import time
def init1(d: dict):
for i in range(1000):
l = []
for k in range(i):
l.append(k)
d[i] = l
def init2(d: dict):
for i in range(1000):
l = []
d[i] = l
for k in range(i):
l.append(i)
def test1():
import multiprocess as mp
with mp.Manager() as manager:
d = manager.dict()
p = mp.Process(target=init1, args=(d,))
p.start()
p.join()
print(d)
def test2():
import multiprocess as mp
with mp.Manager() as manager:
d = manager.dict()
p = mp.Process(target=init2, args=(d,))
p.start()
p.join()
print(d)
start = time.time()
test1()
end = time.time()
print('test1: ', end - start)
start = time.time()
test2()
end = time.time()
print('test2: ', end - start)
使用管道的可能解决方案。在我的电脑上,这需要 870 毫秒,而 test1
的 1.10 秒和 test2
.
的 200 毫秒
def init3(child_conn):
d = {}
for i in range(1000):
l = []
for k in range(i):
l.append(i)
d[i] = l
child_conn.send(d)
def test3():
import multiprocess as mp
parent_conn, child_conn = mp.Pipe(duplex=False)
p = mp.Process(target=init3, args=(child_conn,))
p.start()
d = parent_conn.recv()
p.join()
在 jupyter 上,通过使用魔法 %timeit
我得到:
In [01]: %timeit test3()
872 ms ± 11.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [02]: %timeit test2()
199 ms ± 1.72 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [03]: %timeit test1()
1.09 s ± 10.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我需要用 Python 3.6 在多进程中做一些事情。也就是说,我必须更新一个添加对象列表的字典。由于这些对象是不可拾取的,因此我需要使用 dill
而不是 pickle
和 multiprocess
来自 pathos
而不是 multiprocessing
,但这不应该是问题所在。
将列表添加到字典需要在添加到字典之前重新序列化列表。这会减慢一切,并且花费与没有多处理相同的时间。你能建议我一个解决方法吗?
这是我的 python 3.6 代码:
init1
工作正常但速度慢,init2
速度快但坏了。其余仅供测试。
import time
def init1(d: dict):
for i in range(1000):
l = []
for k in range(i):
l.append(k)
d[i] = l
def init2(d: dict):
for i in range(1000):
l = []
d[i] = l
for k in range(i):
l.append(i)
def test1():
import multiprocess as mp
with mp.Manager() as manager:
d = manager.dict()
p = mp.Process(target=init1, args=(d,))
p.start()
p.join()
print(d)
def test2():
import multiprocess as mp
with mp.Manager() as manager:
d = manager.dict()
p = mp.Process(target=init2, args=(d,))
p.start()
p.join()
print(d)
start = time.time()
test1()
end = time.time()
print('test1: ', end - start)
start = time.time()
test2()
end = time.time()
print('test2: ', end - start)
使用管道的可能解决方案。在我的电脑上,这需要 870 毫秒,而 test1
的 1.10 秒和 test2
.
def init3(child_conn):
d = {}
for i in range(1000):
l = []
for k in range(i):
l.append(i)
d[i] = l
child_conn.send(d)
def test3():
import multiprocess as mp
parent_conn, child_conn = mp.Pipe(duplex=False)
p = mp.Process(target=init3, args=(child_conn,))
p.start()
d = parent_conn.recv()
p.join()
在 jupyter 上,通过使用魔法 %timeit
我得到:
In [01]: %timeit test3()
872 ms ± 11.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [02]: %timeit test2()
199 ms ± 1.72 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [03]: %timeit test1()
1.09 s ± 10.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)