If 语句在 dask 数组上
If statement over dask array
大家好,你能告诉我为什么 dask 数组上的 If 语句这么慢以及如何解决它吗?
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
我看了看dask源代码。本质上,当您在 dask 数组上调用函数时,它会执行数组的 "reduction"。直觉上这是必要的,因为在幕后,dask 数组存储为单独的 "blocks",可以单独存在于内存、磁盘等中,但您需要以某种方式将它们的各个部分拉在一起以进行函数调用。
所以您注意到的时间是在执行缩减的初始开销中。请注意,如果将数组的大小增加到 2M,它所花费的时间与 200 大致相同。在 20M 时,它只需要大约 1s。
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
默认情况下,Dask 数组是惰性的,因此在您对数组调用 .compute()
之前不会执行任何工作。
在你的例子中,当你将 dask 数组放入 if 语句时,你隐式调用了 .compute()
,它将事物转换为布尔值。
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,
...
大家好,你能告诉我为什么 dask 数组上的 If 语句这么慢以及如何解决它吗?
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
我看了看dask源代码。本质上,当您在 dask 数组上调用函数时,它会执行数组的 "reduction"。直觉上这是必要的,因为在幕后,dask 数组存储为单独的 "blocks",可以单独存在于内存、磁盘等中,但您需要以某种方式将它们的各个部分拉在一起以进行函数调用。
所以您注意到的时间是在执行缩减的初始开销中。请注意,如果将数组的大小增加到 2M,它所花费的时间与 200 大致相同。在 20M 时,它只需要大约 1s。
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
默认情况下,Dask 数组是惰性的,因此在您对数组调用 .compute()
之前不会执行任何工作。
在你的例子中,当你将 dask 数组放入 if 语句时,你隐式调用了 .compute()
,它将事物转换为布尔值。
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,
...