Если заявление над массивом dask - PullRequest
0 голосов
/ 22 октября 2018

Привет всем, вы можете сказать мне, почему оператор If в массиве dask такой медленный и как его решить?

import dask.array as da
import time

x = da.random.binomial(1, 0.5, 200, 200)
s = time.time()
if da.any(x):
    e = time.time()
    print('duration = ', e-s)

output: duration =  0.368

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Массив Dask по умолчанию ленив, поэтому никакой работы не произойдет, пока вы не вызовете .compute() для своего массива.

В вашем случае вы неявно вызываете .compute(), когда помещаете свой массив dask в оператор if, который преобразует вещи в логические значения.

x = da.random.random(...)  # this is free
y = x + x.T  # this is free
z = y.any()  # this is free

if z:  # everything above happens now, 
    ...
0 голосов
/ 22 октября 2018

Я взглянул на исходный код dask.По сути, когда вы вызываете функции для массивов dask, он выполняет «сокращение» массива.Интуитивно это необходимо, потому что за кулисами массивы dask хранятся в виде отдельных «блоков», которые могут жить отдельно в памяти, на диске и т. Д., Но вам нужно как-то собрать их части вместе для вызовов функций.

Таким образом, время, которое вы замечаете, находится на начальном этапе выполнения сокращения.Обратите внимание, что если вы увеличите размер массива до 2М, это займет примерно столько же времени, сколько для 200. При 20М это займет всего около 1 с.

import dask.array as da
import time

# 200 case
x = da.random.binomial(1, 0.5, 200, 200)
print x.shape
s = time.time()
print "start"
if da.any(x):
    e = time.time()
    print 'duration = ', e-s

# duration =  0.362557172775


# 2M case
x = da.random.binomial(1, 0.5, 2000000, 2000000)
print x.shape
s = time.time()
print "start"
if da.any(x):
    e = time.time()
    print 'duration = ', e-s

# duration =  0.132781982422

# 20M case
x = da.random.binomial(1, 0.5, 20000000, 20000000)
print x.shape
s = time.time()
print "start"
if da.any(x):
    e = time.time()
    print 'duration = ', e-s

# duration =  1.08430886269


# 200M case
x = da.random.binomial(1, 0.5, 200000000, 200000000)
print x.shape
s = time.time()
print "start"
if da.any(x):
    e = time.time()
    print 'duration = ', e-s

# duration =  8.83682179451
...