【发布时间】:2019-01-04 14:32:04
【问题描述】:
首先对不起我的英语不完美。
我认为我的问题很容易解释。
result={}
list_tuple=[(float,float,float),(float,float,float),(float,float,float)...]#200k tuples
threshold=[float,float,float...] #max 1k values
for tuple in list_tuple:
for value in threeshold:
if max(tuple)>value and min(tuple)<value:
if value in result:
result[value].append(tuple)
else:
result[value]=[]
result[value].append(tuple)
list_tuple 包含大约 200k 元组,我必须非常快地执行此操作(在普通电脑上最多 2/3 秒)。
我的第一次尝试是使用 prange() 在 cython 中执行此操作(因此我可以从 cython 优化和并行执行中受益),但问题是(一如既往),GIL:在 prange() 中我可以使用 cython memviews 管理列表和元组,但我无法将结果插入到字典中。
在 cython 中,我也尝试使用 c++ std 的 unordered_map,但现在的问题是我无法在 c++ 中创建数组向量(这将是我的 dict 的值)。
第二个问题类似:
list_tuple=[((float,float),(float,float)),((float,float),(float,float))...]#200k tuples of tuples
result={list_tuple[0][0]:[]}
for tuple in list_tuple:
if tuple[0] in result:
result[tuple[0]].append(tuple)
else:
result[tuple[0]]=[]
这里我还有另一个问题,如果想使用 prange() 我必须使用自定义哈希函数来使用数组作为 c++ unordered_map 的键
如你所见,我的 sn-ps 并行运行非常简单。
我想尝试使用 numba,但可能会因为 GIL 而相同,而且我更喜欢使用 cython,因为我需要二进制代码(这个库可能是商业软件的一部分,所以只允许使用二进制库) .
总的来说,我希望避免使用 c/c++ 函数,我希望找到一种方法来并行管理诸如 dicts/lists 之类的东西,同时具有 cython 性能,尽可能地保留在 Python 域中;但我愿意接受所有建议。
谢谢
【问题讨论】:
-
您可以查看
numpy,因为您的问题可以向量化。首先计算每个元组的阈值索引,然后您可以根据索引创建字典。这将产生显着的加速。 -
multiprocessing可以并行化此任务 - docs.python.org/2/library/multiprocessing.html。 -
代替
result={}, .../lines/of/code..result[value]=[]; result[value].append(tuple),你可以使用result=defaultdict(list)..../lines/of/code....result[value].append(tuple)。defaultdict在collections模块中可用 -from collections import defaultdict -
@a_guest 我不知道矢量化是什么,我认为您在谈论en.wikipedia.org/wiki/Array_programming 您能更好地说明 numpy 如何帮助我解决矢量化问题吗? numpy 能解决我的多核问题吗?
-
@Shiva 是的,我考虑过这个选项,但我认为不能将多处理本机库与 cython 一起使用,并且使用 cython 单核(因此使用 GIL、dict、ecc)的速度比使用更多只是多线程中的python。对于你是对的集合字典,我会使用它。
标签: python c++11 parallel-processing cython numba