为什么使用多处理并没有更快?我做错了吗?

时间:2019-03-24 04:29:48

标签: python multiprocessing

我制作了一个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个进程,一个测试奇数,另一个测试偶数,它可以工作,但并没有比正常方法更快。 我期望它在多处理中的速度快两倍。

2 个答案:

答案 0 :(得分:3)

您正在就地调用函数,并将结果提供给多处理。您必须将函数作为可调用函数和参数分别提交:

multiprocessing.Process(target=per1, args=(x,))

答案 1 :(得分:0)

首先,我们将对您的数学问题有何见解提供一些优化,这些优化可能会加快执行速度。简而言之,我可以确定一些事情,包括:

  • 您要检查"steps 1"是否写在resolve.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在程序执行过程中至少打开了两次,也许更多,具体取决于堆栈中有多少个调用per1
  • Klaus D显示了调用该函数的正确方法,但还请注意,您仅在.start()x = 2001时才调用y = 2002。这立即导致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()
  • 还请注意,启动多进程很昂贵,但是一旦启动便非常高效,因此仅当您知道程序将花费很长时间为每个进程运行时才应使用。希望这会有所帮助:)