我正在使用 multiprocessing.Queue
传递 float64
的 numpy 数组python进程之间。这工作正常,但我担心它可能不会像它应该的那样有效。
根据 multiprocessing
的文档, 物体放置在 Queue
上会被 pickle 。打电话pickle
在 numpy 数组上生成数据的文本表示,因此空字节被字符串 "\\x00"
替换.
>>> pickle.dumps(numpy.zeros(10))
"cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I10\ntp6\ncnumpy\ndtype\np7\n(S'f8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'<'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\np13\ntp14\nb."
我担心这意味着我的数组被昂贵地转换成原始大小的 4 倍,然后在另一个过程中转换回来。
有没有办法以原始未更改的形式通过队列传递数据?
我知道共享内存,但如果这是正确的解决方案,我不确定如何在其上构建队列。
谢谢!
最佳答案
问题不在于 numpy,而是关于如何 pickle 的默认设置表示数据(作为字符串,因此输出是人类可读的)。你可以change the default settings for pickle而是生成二进制数据。
import numpy
import cPickle as pickle
N = 1000
a0 = pickle.dumps(numpy.zeros(N))
a1 = pickle.dumps(numpy.zeros(N), protocol=-1)
print "a0", len(a0) # 32155
print "a1", len(a1) # 8133
另请注意,如果您想减少处理器的工作量和时间,您可能应该使用 cPickle
而不是 pickle(但无论 pickle 版本如何,使用二进制协议(protocol)都可以节省空间) .
关于共享内存:
关于共享内存的问题,有几点需要考虑。共享数据通常会显着增加代码的复杂性。基本上,对于使用该数据的每一行代码,您都需要担心另一个进程中的其他代码行是否同时使用该数据。这有多难将取决于你在做什么。优点是您可以节省来回发送数据的时间。 Eelco 引用的问题是一个 60GB 阵列,为此真的别无选择,它必须共享。另一方面,对于大多数相当复杂的代码,决定共享数据只是为了节省几微秒或字节可能是人们可能做出的最糟糕的过早优化之一。
关于python - 通过 multiprocessing.Queue 传递 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21409683/