我做了一个python脚本来解决一个复杂的数学问题,并将结果写入文本文件。 但这需要很长时间,所以我想让它更多地利用我的 i7-7700K,因为它只使用 18%。 所以我尝试使用多处理。 但它并不快。我做错了吗? (旁注)当我使用多处理运行它时,文本文件完成后为空白。我不知道为什么。
我看了一堆关于如何使用多处理的YouTube视频。
import time
import multiprocessing
solve = open("solve.txt", "w")
def per1(n, steps=0):
if steps == 0:
print(n)
if len(str(n))==1:
print("Total steps " + str(steps))
return "Done"
steps += 1
digits = [int(i) for i in str (n)]
result = 1
for j in digits:
result *= j
# print(result)
per1(result, steps)
S = 2
solve = open("solve.txt", "r")
if 'steps 1' in open('solve.txt').read():
S = 2
if 'steps 2' in open('solve.txt').read():
S = 3
if 'steps 3' in open('solve.txt').read():
S = 4
if 'steps 4' in open('solve.txt').read():
S = 5
if 'steps 5' in open('solve.txt').read():
S = 6
if 'steps 6' in open('solve.txt').read():
S = 7
if 'steps 7' in open('solve.txt').read():
S = 8
if steps == S:
solve = open("solve.txt", "a")
solve.write("# steps ")
solve.write(str(steps))
solve.write("n")
solve.write("x = ")
solve.write(str(x))
# solve.write(" results ")
# solve.write(str(result))
solve.write("n")
x = 1
y = 2
# with multiprocessing
if __name__ == "__main__":
while x <= 2000:
# while x <= 277777788888899:
p1 = multiprocessing.Process(target=per1(x)) #works ish
# p1 = multiprocessing.Process(target=per1, args=(x,)) #does not work
print("P1")
p2 = multiprocessing.Process(target=per1(y)) #works ish
# p2 = multiprocessing.Process(target=per1, args=(y,)) #does not work
print("P2")
# per1(x)
x += 2
y += 2
p1.start()
p2.start()
p1.join()
p2.join()
# normal way
# while x <= 2000:
# # while x <= 277777788888899:
# per1(x)
# x += 1
print("My program took", time.time() - start_time, "to run")
solve = open("solve.txt", "a")
solve.write(str(time.time() - start_time))
solve.close()
我将其分为 2 个进程,一个测试奇数,另一个测试偶数,它可以工作,但它并不比正常方式快。 我预计它的速度是多处理的两倍。
您正在就地调用函数并将结果提供给多处理。您必须将函数作为可调用对象和参数分别提交:
multiprocessing.Process(target=per1, args=(x,))
首先,将注意到一些关于你的数学问题的见解将有助于提供一些优化,否则可能会加快执行速度。简单地看一下,我可以确定有几件事,包括:
- 您检查
"steps 1"
是否写在 solve.txt 中,这永远不会是这种情况,因为 S 至少为 2(或更多),并且您检查是否steps == S
要访问步骤 N, - 您必须之前访问过所有步骤 2 到步骤 N-1。这意味着编写类似以下代码的内容是有效的。这也将节省大量不必要的检查(也许知道问题是什么可以做得更少,或者节省检查内存的时间):
# since once 'S' isn't found, n >= S will not be in solve.txt
S = 2
while ("steps " + str(S)) in open('solve.txt').read() and S < 8:
S += 1
- solve.txt 在程序期间至少打开 2 次,也许更多,具体取决于堆栈中对 per1 的调用次数
- Klaus D 已经展示了调用函数的正确方法,但也请注意,您只在
x = 2001
和y = 2002
时调用.start()
。这会立即导致result
变为 0,因此不会保存任何结果(因为长度为 0 等于 1),返回时没有任何 IO。你会想做这样的事情(未经测试):
def driver(start, end, step):
for i in range(start, end+1, step):
per1(i)
p1 = multiprocessing.Process(target=driver, args=(1, 2000, 2))
p2 = multiprocessing.Process(target=driver, args=(0, 2000, 2))
p1.start()
p2.start()
p1.join()
p2.join()
- 另请注意,多进程的启动成本很高,但一旦启动就会高效,因此仅当您知道程序需要很长时间才能为每个进程运行时才应使用。希望这对:)有所帮助