使用多处理加速python中的IO

时间:2016-01-24 23:52:16

标签: python multiprocessing

我有一些代码可以读取几个数据集,键入(称之为)“year”,然后加入一些数据集。我试图通过并行化问题的“读取”部分来加速代码。我这样写了这个函数:

现在,这段代码确实并行启动了几个进程,并且每个进程都快速完成,但整个运行时最终比简单地连续执行这些读取要快。

我做错了什么?

def parallelQueueRead():                                                         
  start_time = timeit.default_timer()                                             
  myq = Queue()

  def reader(year, q):                                                            
    loc_start_time = timeit.default_timer()                                        
    print("reading year %s" % (year))                                                                                      
    astore = store(year)                                  
    df = astore.getAllData(TESTSPEC)                                               
    astore.close()                                                                 
    q.put((year, df))                                                              
    print("finished reading year %s ,took: %s" %                                   
      (year, str(timeit.default_timer() - loc_start_time)))

  processes = [Process(target = reader, args = (y, myq)) for y in CHUNKS ]        
  for p in processes:                                                             
    p.start()              

  results = [ myq.get() for p in processes ]                                      
  results = sorted(results, key = lambda x: x[0])     

  print("parallel read took: " + str(timeit.default_timer() - start_time))

输出:

reading year 2011
reading year 2012
reading year 2013
reading year 2014
reading year 2015
finished reading year 2011 ,took: 1.142295703291893
finished reading year 2014 ,took: 1.2605517469346523
finished reading year 2013 ,took: 1.2637327639386058
finished reading year 2012 ,took: 1.2874943045899272
finished reading year 2015 ,took: 1.7436037007719278
parallel read took: 5.500953913666308

另一个例程的输出,它只在一个过程中连续执行相同的操作:

serial read took: 5.3680868614465

后脚本1

只是为了澄清:串行版本是一个简单的for循环:

results = [] 
for year in CHUNKS:
    results += [ astore.getAllData(TESTSPEC) ]

后脚本2

在阅读文档时,我认为并行版本缓慢的原因是由于腌制大型数据集(读者的结果)。执行此操作所花费的时间包括在每个选取器报告的时间中(此外,取消结果所花费的时间包括在总时间中)。

这对我来说真是太可怕了,因为这意味着多处理无法加速我的代码执行。

1 个答案:

答案 0 :(得分:1)

根据df中数据的结构(astore.getAllData(TESTSPEC)的结果),您可以尝试使用sharedctypes将收集的数据存储在共享内存中。当然,这种方法主要用于“POD” - 仅数据结构,不包含任何代码或复杂对象。

此外,我会将整个数据处理移动到子节点,并确保astore实际上能够并行工作,无需同步(或至少最小化同步时间)客户端(不同进程)。

但当然所有这些建议都是基于“常识”和#39; - 如果没有关于您的应用内部和准确分析的准确知识,很难确切地说出什么是最适合您的解决方案