использование dask для очистки запросов - PullRequest
0 голосов
/ 15 мая 2018

Мне нравится простота 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()

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Есть существенные различия между multiprocessing и multithreading. Смотрите мой ответ здесь для краткого комментария по различиям.В вашем случае это приводит только к ускорению в 2 раза вместо, скажем, ускорения в 10–50 раз плюс.

По сути, ваша проблема не масштабируется, а добавляется больше ядер, чем при добавлении потоков (так какэто связано с вводом / выводом ... не связано с процессором).

Настройка Dask для работы в режиме multithreaded вместо режима multiprocessing.Я не уверен, как это сделать в dask, но эта документация может помочь

0 голосов
/ 15 мая 2018

Во-первых, 2-кратное ускорение - ура!

Вы можете начать с чтения http://dask.pydata.org/en/latest/setup/single-machine.html

Короче говоря, здесь могут быть важны следующие три вещи:

  • у вас есть только одна сеть, и все данные должны проходить через нее, так что это может быть узким местом
  • по умолчанию, вы используете потоки для распараллеливания, но Python GIL ограничивает параллельное выполнение (см. ссылку выше)
  • операция concat выполняется в одной задаче, поэтому ее нельзя распараллелить, и с некоторыми типами данных она может составлять существенную часть общего времени.Вы также рисуете все окончательные данные в процессе вашего клиента с .compute().
...