Python 并行化/加速独特的子串生成技术
我正在尝试生成重复4个字符的独特组合(例如,我正在编写的python脚本的a、b、c和d)Python 并行化/加速独特的子串生成技术,python,string,multiprocessing,python-multiprocessing,Python,String,Multiprocessing,Python Multiprocessing,我正在尝试生成重复4个字符的独特组合(例如,我正在编写的python脚本的a、b、c和d) {Depth_value --> Output To Be Generated} - 1 --> [a, b, c, d] - 2 --> [a, b, c, d, aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd] - 3 --> [a, b, c, d, aa, ab, ac, ad, ba,
{Depth_value --> Output To Be Generated}
- 1 --> [a, b, c, d]
- 2 --> [a, b, c, d, aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd]
- 3 --> [a, b, c, d, aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd, aaa, aab, aac, aad, ..., ddd]
- .
- .
- .
- N --> [a, b, c, d, aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd, aaa, aab, aac, aad, ..., (ddd...d)]
编辑1 执行^代码不到一秒钟。我想这是我对这条语句的结果所做的事情造成了瓶颈
depth = int(sys.argv[1])
UniquePatterns = ["".join(x) for i in range(1, depth + 1) for x in product(*['ATCG'] * i)]
print("Scanning dataset for" + str(len(UniquePatterns)) + " unique patterns!")
UniqueCountPatterns = UniquePatterns
GDS = {}
GDS_UniqueCount = dict(zip(UniqueCountPatterns, [0 for i in range(1, NumberOf(UniqueCountPatterns)+1)]))
GDS['UniqueCount'] = GDS_UniqueCount
mngr = Manager()
GDS_Links = mngr.dict()
GDS_Links = dict(zip(UniquePatterns, [0 for i in range(1, NumberOf(UniquePatterns)+1)]))
for l in dict(zip(UniquePatterns, [0 for i in range(1, NumberOf(UniquePatterns)+1)])):
GDS_Links[l] = dict(zip(UniquePatterns, [0 for i in range(1, NumberOf(UniquePatterns)+1)]))
对有效地填充字典有什么建议吗
这就是我生成独特模式列表的方式。虽然,在深度值为6之前,这非常有效,但要生成超出该值的模式,需要花费大量时间 我的整个python脚本是一个高度并行化的脚本,计算超过“depth”变量值6的唯一组合所需的时间非常长,这成为我整个过程的瓶颈 是否有可能并行化该代码以高效、有效地生成唯一的组合是“可接受的”时间。(在我的应用程序上下文中,“可接受的”定义的范围从几秒钟到大约1分钟) 我试图通过使用一个核心进程来并行化这个计算的某些方面,以下面的方式使用多处理在一个进程中计算具有一定长度重复的唯一组合
from itertools import product, chain
from multiprocessing import Pool, Process, Manager
def logic_patterncounting(inp1):
return ["".join(x) for x in product(*['abcd'] * inp1)]
# UniquePatterns = ["".join(x) for i in range(1, 7 + 1) for x in product(*['ATCG'] * i)]
if __name__ == '__main__':
depth = 2
UniquePatterns = []
pool = Pool()
UniquePatterns = chain(*pool.map(logic_patterncounting, range(1, depth + 1)))
print(list(UniquePatterns))
pool.close()
pool.join()
这不是实现我想要的最佳方法。对于更大的深度值,如何增加相同的计算
解决方案 运行一个单独的进程,不断生成唯一的模式并将其存储在一个单独的文件中。对于更大的深度值,生成唯一模式所需的时间仍然很长,但是在主应用程序执行0时这些模式的可用性修复了瓶颈。对主应用程序进行编码以利用随时可用的lis通过将文件内容读入字典或列表结构(取决于使用情况)来实现模式的转换
另外,除非没有其他解决方案,否则我不想求助于解决方案。因为您是按长度建立值,也许您可以(不使用多处理)通过重用以前的列表来优化它。您只需要调用product()然后使用两个序列。例如,一次2将是一次一个,一次3将是一次一个,一次2,一次4将是一次2*2,等等。当我运行生成排列的代码行时,几乎不需要任何时间——对于
depth=10
,生成1398,不到1秒100排列。(a)你确定你理解是什么导致你的大型程序运行缓慢。和(b)您需要支持多大的depth
?对于depth=13
,大约需要9秒,生成89478484
置换。在后一种情况下,我不构建一个只需对结果进行迭代即可。@FMc o.0如果我启动python3.4 shell并尝试代码,它将永远无法处理。尽管如果我运行脚本仅包含一行代码和import语句,使用命令行独立运行,它可以像您建议的那样在不到一秒钟的时间内处理。瓶颈很可能存在于较大程序的其他地方。@FMc瓶颈很可能存在于较大程序的其他地方。(a)我之所以认为这是瓶颈,是因为在我执行较大的程序时,如果我将深度大小从6减少到3或4,我可以在大约5分钟左右完成较大的程序执行(这是计算密集型的)。(b)我需要支持高达12的深度值。行UniquePatterns=[…]在不到1秒的时间内运行depth=10
。可能您正在尝试只运行部分[…]
,而打印整个结果列表确实需要花费很长时间。由于您是按长度建立值的,可能您可以(不使用多处理)通过重用以前的列表对其进行优化。您只需调用product()然后使用两个序列。例如,一次2将是一次一个,一次3将是一次一个,一次2,一次4将是一次2*2,等等。当我运行生成排列的代码行时,几乎不需要任何时间——对于depth=10
,生成1398,不到1秒100排列。(a)你确定你理解是什么导致你的大型程序运行缓慢。和(b)您需要支持多大的depth
?对于depth=13
,大约需要9秒,生成89478484
置换。在后一种情况下,我不构建一个只需对结果进行迭代即可。@FMc o.0如果我启动python3.4 shell并尝试代码,它将永远无法处理。尽管如果我运行脚本仅包含一行代码和import语句,使用命令行独立运行,它可以像您建议的那样在不到一秒钟的时间内处理。瓶颈很可能存在于较大程序的其他地方。@FMc瓶颈很可能存在于较大程序的其他地方。(a)我之所以认为这是瓶颈,是因为在我执行较大的程序时,如果我将深度大小从6减少到3或4,我可以在大约5分钟左右完成较大的程序执行(这是计算密集型的)。(b)我需要支持高达12的深度值。行UniquePatterns=[…]在不到1秒的时间内运行depth=10
。可能您正在尝试只运行部分[…]
,而打印整个结果列表确实需要花费很长时间。
from itertools import product, chain
from multiprocessing import Pool, Process, Manager
def logic_patterncounting(inp1):
return ["".join(x) for x in product(*['abcd'] * inp1)]
# UniquePatterns = ["".join(x) for i in range(1, 7 + 1) for x in product(*['ATCG'] * i)]
if __name__ == '__main__':
depth = 2
UniquePatterns = []
pool = Pool()
UniquePatterns = chain(*pool.map(logic_patterncounting, range(1, depth + 1)))
print(list(UniquePatterns))
pool.close()
pool.join()