FOR嵌套循环的多重处理 [英] Multiprocessing of for nested loops

查看:24
本文介绍了FOR嵌套循环的多重处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行以下代码,以将列表DATA_SET_N保存在末尾。

import re
data_set_N=[]    
for i_1 in list(range(10))+list("+-"):
    for i_2 in list(range(10))+list("+-*/")+["=="]:
        for i_3 in list(range(10))+list("+-*/")+["=="]:
            for i_4 in list(range(10))+list("+-*/")+["=="]:
                for i_5 in list(range(10))+list("+-*/")+["=="]:
                    for i_6 in list(range(10))+list("+-*/")+["=="]:
                        for i_7 in list(range(10))+list("+-*/")+["=="]:
                            for i_8 in list(range(10)):
                                try :
                                    value= str(i_1)+str(i_2)+str(i_3)+str(i_4)+str(i_5)+str(i_6)+str(i_7)+str(i_8)
                                    valuev=re.sub(r'0+(?!)', '', value)
                                    evaluation = eval(valuev)
                                    if type(evaluation) == type(True) and evaluation and "//" not in value:
                                        data_set_N.append(value)

                                except:
                                    continue
print(len(data_set_N))

问题是需要50多个小时,第一个I_1需要4.5个小时。 为了获得更快的data_set_N,我想使用多处理。我们的想法是使用如下内容:

from multiprocessing import Process, Manager
import itertools    
import re

def add_value(data_set_N,paramlist):
    #I am not sure if this function is well defined
    try 
        i_1,i_2,i_3,i_4 = paramlist[0],paramlist[1],paramlist[2],paramlist[3]
        i_5,i_6,i_7,i_8 = paramlist[4],paramlist[5],paramlist[6],paramlist[7]
        value = str(i_1)+str(i_2)+str(i_3)+str(i_4)+str(i_5)+str(i_6)+str(i_7)+str(i_8)
        valuev =re.sub(r'0+(?!)', '', value)
        evaluation = eval(valuev)
        if type(evaluation) == type(True) and evaluation and "//" not in value:
            data_set_N.append(value)

    except:
        return     
        
        
data_set_N = [] 
#Generate values for each parameter
I_1 = list(range(10))+list("+-")
I_2 = list(range(10))+list("+-*/")+["=="]
I_3 = list(range(10))+list("+-*/")+["=="]
I_4 = list(range(10))+list("+-*/")+["=="]
I_5 = list(range(10))+list("+-*/")+["=="]
I_6 = list(range(10))+list("+-*/")+["=="]
I_7 = list(range(10))+list("+-*/")+["=="]
I_8 = list(range(10))
paramlist = list(itertools.product(I_1,I_2,I_3,I_4,I_5,I_6,I_7,I_8))

if __name__ == "__main__":
    with Manager() as manager:
        data_set_N = manager.list()  # <-- can be shared between processes.
        processes = []

        for i in range(10): #os.cpu_count() - 2 =10 , this range can be changed
            p = Process(target=add_value, args=(data_set_N,paramlist))  # Passing the list
            p.start()
            processes.append(p)

        for p in processes:
            pool.close()
            pool.join()

        data_set_N = list(data_set_N) #the final list

此处的问题是paramlist导致MemoryError(因为其大小为12x15^6x10)。

有没有办法使用多处理来更快地(大约10小时)执行代码,同时避免内存问题?

推荐答案

我会做的是:

  1. 使用多进程池。
  2. 保持基本代码不变,但有7个嵌套循环(7个内部循环),并且每个提交的任务都在处理i_1列表中的一个值。
  3. 在计算value之后立即移动廉价的'//' in value检查,并可能避免执行不必要的正则表达式替换和调用eval函数。
这将使用最多12个核心(i_1列表的长度),如果您的计算机有这些核心的话。如果您的计算机有12个核它们都是物理核没有其他核在运行,我预计执行时间将减少12倍。如果您有6个物理核和6个逻辑核,并且其他进程正在运行,那么执行时间显然不会减少12倍(我无法预测减少多少)。但这是解决您的记忆问题的最简单方法。

如果您有比12个内核多得多的内核,那么您可以定义process_value拥有6个最内部的循环,并使用方法starmap(iterable的每个元素将是一个元组,process_value现在除了托管列表外还有两个参数,i_1i_2),可迭代参数是i_1列表和i_2列表的乘积。

from multiprocessing import Pool, Manager, cpu_count
from functools import partial
import re


def process_value(data_set_N, i_1):
    for i_2 in list(range(10))+list("+-*/")+["=="]:
        for i_3 in list(range(10))+list("+-*/")+["=="]:
            for i_4 in list(range(10))+list("+-*/")+["=="]:
                for i_5 in list(range(10))+list("+-*/")+["=="]:
                    for i_6 in list(range(10))+list("+-*/")+["=="]:
                        for i_7 in list(range(10))+list("+-*/")+["=="]:
                            for i_8 in list(range(10)):
                                try:
                                    value = str(i_1)+str(i_2)+str(i_3)+str(i_4)+str(i_5)+str(i_6)+str(i_7)+str(i_8)
                                    if '//' in value:
                                        continue
                                    valuev = re.sub(r'0+(?!)', '', value)
                                    evaluation = eval(valuev)
                                    if type(evaluation) == type(True) and evaluation:
                                        data_set_N.append(value)
                                except:
                                    continue

if __name__ == '__main__':
    with Manager() as manager:
        data_set_N = manager.list()
        # The iterable is the i_1 list:
        i_1_list = list(range(10))+list("+-")
        POOL_SIZE = min(cpu_count(), len(i_1_list))
        pool = Pool(POOL_SIZE)
        pool.map(partial(process_value, data_set_N), i_1_list)
        pool.close()
        pool.join()
        print(len(data_set_N))

这篇关于FOR嵌套循环的多重处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆