我喜欢简单的dask,并喜欢用它来刮刮当地的超市。我的multiprocessing.cpu_count()是4,但是这段代码只能实现2倍的加速。为什么呢?
from bs4 import BeautifulSoup
import dask, requests, time
import pandas as pd
base_url = 'https://www.lider.cl/supermercado/category/Despensa/?No={}&isNavRequest=Yes&Nrpp=40&page={}'
def scrape(id):
page = id+1; start = 40*page
bs = BeautifulSoup(requests.get(base_url.format(start,page)).text,'lxml')
prods = [prod.text for prod in bs.find_all('span',attrs={'class':'product-description js-ellipsis'})]
prods = [prod.text for prod in prods]
brands = [b.text for b in bs.find_all('span',attrs={'class':'product-name'})]
sdf = pd.DataFrame({'product': prods, 'brand': brands})
return sdf
data = [dask.delayed(scrape)(id) for id in range(10)]
df = dask.delayed(pd.concat)(data)
df = df.compute()
答案 0 :(得分:4)
首先,加速2倍 - 欢呼!
您需要先阅读http://dask.pydata.org/en/latest/setup/single-machine.html
简而言之,以下三件事可能很重要:
concat
操作发生在单个任务中,因此无法并行化,并且某些数据类型可能是总时间的重要部分。您还使用.compute()
将所有最终数据绘制到客户的流程中。答案 1 :(得分:0)
multiprocessing
和multithreading
之间存在显着差异。 See my answer here对差异进行简要评论。在你的情况下,只能获得2倍的加速,而不是10倍 - 50倍以上的加速。
基本上,通过添加更多内核,您的问题也不会扩展,因为它会添加线程(因为它的I / O绑定...不受处理器限制)。
将Dask配置为以multithreaded
模式而非multiprocessing
模式运行。我不确定如何在dask
中执行此操作,但this documentation可能有帮助