我正在尝试并行化一个在 Python 中接收对象的函数:
在使用 Pathos 时,map 函数会在将对象分发到处理器之前自动对对象进行挖掘。
但是,每次对对象进行挖掘大约需要 1 分钟,并且我需要运行此函数最多 100 次。总而言之,在运行之前序列化对象需要将近 2 个小时。
有没有办法只序列化一次,并多次使用它?
非常感谢
我正在尝试并行化一个在 Python 中接收对象的函数:
在使用 Pathos 时,map 函数会在将对象分发到处理器之前自动对对象进行挖掘。
但是,每次对对象进行挖掘大约需要 1 分钟,并且我需要运行此函数最多 100 次。总而言之,在运行之前序列化对象需要将近 2 个小时。
有没有办法只序列化一次,并多次使用它?
非常感谢
最简单的方法是手动执行此操作。
如果没有您的代码示例,我必须做出很多假设并写一些非常模糊的东西,所以让我们以最简单的情况为例。
假设您正在dill
手动使用,因此您现有的代码如下所示:
obj = function_that_creates_giant_object()
for i in range(zillions):
results.append(pool.apply(func, (dill.dumps(obj),)))
您所要做的就是移出dumps
循环:
obj = function_that_creates_giant_object()
objpickle = dill.dumps(obj)
for i in range(zillions):
results.append(pool.apply(func, (objpickle,)))
但是根据您的实际使用情况,最好只在前面粘贴一个缓存dill
:
cachedpickle = functools.lru_cache(maxsize=10)(dill.dumps)
obj = function_that_creates_giant_object()
for i in range(zillions):
results.append(pool.apply(wrapped_func, (cachedpickle(obj),))
当然,如果您要multiprocessing
使用monkeypatching 来dill
代替pickle
,您可以轻松地对其进行修补以使用此cachedpickle
功能。
如果您使用的是 ,它是预替换的multiprocess
分叉版本,那么如何修补它就不那么明显了;您需要浏览源代码并查看它在哪里使用并让它使用您的包装器。但是 IIRC,它只是做了一个地方,然后使用与(稍微过时的版本)相同的代码,所以它并没有那么不同。multiprocessing
dill
pickle
dill
import dill as pickle
multiprocessing
事实上,您甚至可以编写一个模块来公开与pickle
和相同的接口dill
:
import functools
import dill
def loads(s):
return dill.loads(s)
@lru_cache(maxsize=10)
def dumps(o):
return dill.dumps(o)
…然后将其替换import dill as pickle
为import mycachingmodule as pickle
.
…甚至在加载后对其进行monkeypatch (或任何适当的名称-您仍然必须在您使用的任何东西的源代码中multiprocess.helpers.pickle = mycachingmodule
找到相关的发生位置)。import
这和它可能得到的一样复杂。