我几乎是几个月学习python的新程序员。在过去的两周里,我一直在编写一个脚本来搜索构成幻方的数字排列。
最后,我成功地在30秒内搜索了整个880个4x4魔方数集。之后我制作了一些不同的Perimeter Magic Square程序。它发现超过10,000,000个排列,因此我想将它们逐个存储到文件中。问题是我的程序没有使用我的所有进程,当它正在将一些部分数据存储到文件时,它会停止搜索新的数字集。我希望我可以让我的CPU继续搜索一个进程,其他进程将搜索到的数据存储到文件中。
以下是与我的魔方计划相似的结构。
while True:
print('How many digits do you want? (more than 20): ', end='')
ansr = input()
if ansr.isdigit() and int(ansr) > 20:
ansr = int(ansr)
break
else:
continue
fileNum = 0
itemCount = 0
def fileMaker():
global fileNum, itemCount
tempStr = ''
for i in permutationList:
itemCount += 1
tempStr += str(sum(i[:3])) + ' : ' + str(i) + ' : ' + str(itemCount) + '\n'
fileNum += 1
file = open('{0} Permutations {1:03}.txt'.format(ansr, fileNum), 'w')
file.write(tempStr)
file.close()
numList = [i for i in range(1, ansr+1)]
permutationList = []
itemCount = 0
def makePermutList(numList, ansr):
global permutationList
for i in numList:
numList1 = numList[:]
numList1.remove(i)
for ii in numList1:
numList2 = numList1[:]
numList2.remove(ii)
for iii in numList2:
numList3 = numList2[:]
numList3.remove(iii)
for iiii in numList3:
numList4 = numList3[:]
numList4.remove(iiii)
for v in numList4:
permutationList.append([i, ii, iii, iiii, v])
if len(permutationList) == 200000:
print(permutationList[-1])
fileMaker()
permutationList = []
fileMaker()
makePermutList(numList, ansr)
我在顶部添加了from multiprocessing import Pool
。然后我用以下内容替换了两个'fileMaker()'部分。
if __name__ == '__main__':
workers = Pool(processes=2)
workers.map(fileMaker, ())
结果呢?不好了。它只是笨拙地工作。就目前而言,多处理对我来说太难了。
任何人,请教我一些东西。我的代码应该如何修改?
答案 0 :(得分:1)
好吧,在回答你的问题之前,先解决一些困扰我的事情。
numList = [i for i in range(1, ansr+1)]
我知道列表理解很酷,但如果你需要将iterable作为一个列表(你可能不需要,但我离题了),请只做list(range(1, ansr+1))
。
def makePermutList(numList, ansr):
...
这非常黑客。有没有理由你不能使用itertools.permutations(numList,n)
?它肯定会更快,更友好的记忆。
最后,回答你的问题:如果你想提高i / o性能,你应该做的最后一件事就是让它成为多线程。我并不是说你不应该这样做,我的意思是它应该是你做的最后一件事。首先重构/改进其他事情。
您需要使用所有使用全局变量的顶级代码,将退格键应用于它,并重写正确传递数据的函数。然后你可以考虑使用线程。我个人会使用from threading import Thread
并手动生成线程来执行每个I / O单元,而不是使用多处理。