我在python中编写了一些程序,它运行类似的步骤,但比以下步骤更复杂:
步骤1:给定长度相同的 BATCH 列表,一个列表中的每个元素代表它可能具有的状态数,我需要DFS所有可能的状态(由0,1表示) ,2 ...)一个列表,并将它们放在一个列表中。例如输入[[1,2,1], [2,2,2]]
,此步骤的输出应为[[0,0,0],[0,1,0],[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
步骤2:计算与STEP 1输出相关的一些值,并返回一个带有以下形式的字典:
{"0,0,0": 0.1,
"0,1,0":0.2,
"0,0,1":0.56,
"0,1,0":0.68,
"0,1,1":0.3242,
"1,0,0":0.8987,
"1,0,1":0.214,
"1,1,0":0.2,
"1,1,1":0.9}
步骤3:在此步骤中,我需要处理 BATCH 列表。处理时,我需要非常频繁地查找(只读取操作)STEP 2返回的dict,并为批处理中的每个列表生成一个元组。
我发现我的程序在STEP 1和STEP 3中确实很慢。由于某种原因,第2步只能在python中出现。而且,批处理列表彼此独立,它们只在STEP 3中共享相同的字典。所以我想使用多线程并行处理这些列表。
由于python有GIL,threading
模块不起作用。
然后我尝试multiprocessing
,甚至更慢(我猜这是因为上下文切换和数据传输)。
然后我使用c ++ 11编写一个.so模块,其中包含接收PyObject
并返回PyObject
的函数。我使用了POXIS线程,但只要我使用多个线程,它总是会引发SegmentFault
错误。我仔细阅读了python-C-API的文档,发现仍然需要GIL,
参考here。所以这根本没有帮助。
然后我使用Cython
通过cdef
声明所有变量的类型,它确实加速但不是那么多。
我在这个问题上迷失了自己。谁能帮我?我真的很感激。