栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么numpy.any在大型数组上这么慢?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么numpy.any在大型数组上这么慢?

正如评论中所猜到的,我可以确认数组的处理是按块完成的。首先,我将向您展示代码中的内容,然后向您展示如何更改块大小以及这样做对基准的影响。

在Numpy源文件中的哪里找到简化处理

np.all(x)与x.all()相同。all()真正调用np.core.umath.logical_and.reduce(x)。

如果您想深入了解numpy源,我将尝试引导您找到使用缓冲区/块大小的方法。我们将要查看的包含所有代码的文件夹是numpy / core / src /
umath /。

ufunc_object.c中的PyUFunc_Reduce()是处理reduce的C函数。在PyUFunc_Reduce()中,可以通过PyUFunc_GetPyValues()函数(ufunc_object.c)在某些全局词典中查找reduce的值来找到块或缓冲区的大小。在我的计算机上,并从开发分支进行编译,块大小为8192。reduce.c中的PyUFunc_ReduceWrapper()被调用以设置迭代器(步长等于块大小),并调用传入的循环函数是ufunc_object.c中的reduce_loop()。

reduce_loop()基本上只使用迭代器,并为每个块调用另一个innerloop()函数。innerloop函数位于loops.c.src中。对于布尔数组和我们的all
/ logical_and案例,适当的innerloop函数是BOOL_logical_and。您可以通过搜索BOOLEAN
LOOPS找到合适的函数,然后找到它下面的第二个函数(由于此处使用类似模板的编程,因此很难找到它)。在那里,您会发现实际上每个块都发生了短路。

如何更改函数(以及任何/全部)中使用的缓冲区大小

您可以使用np.getbuffersize()获得块/缓冲区的大小。对我来说,它返回8192而不需要手动设置它,与通过打印代码中的缓冲区大小找到的匹配。您可以使用np.setbuffersize()更改块大小。

使用更大的缓冲区大小的结果

我将您的基准代码更改为以下代码:

import timeitimport numpy as npprint 'Numpy v%s' %np.version.full_versionstmt = "np.all(x)"for ii in xrange(9):    setup = "import numpy as np; x = np.zeros(%d,dtype=np.bool); np.setbufsize(%d)" %(10**ii, max(8192, min(10**ii, 10**7)))    timer = timeit.Timer(stmt,setup)    n,r = 1,3    t = np.min(timer.repeat(r,n))    while t < 0.2:        n *= 10        t = np.min(timer.repeat(r,n))    t /= n    if t < 1E-3:        timestr = "%1.3f us" %(t*1E6)    elif t < 1:        timestr = "%1.3f ms" %(t*1E3)    else:        timestr = "%1.3f s" %t    print "Array size: 1E%i, %i loops, best of %i: %s/loop" %(ii,n,r,timestr)

Numpy不喜欢缓冲区大小过小或太大,因此我确保它不会小于8192或大于1E7,因为Numpy不喜欢缓冲区大小为1E8。否则,我将缓冲区大小设置为正在处理的数组的大小。我之所以只使用1E8,是因为我的机器目前只有4GB的内存。结果如下:

Numpy v1.8.0.dev-2a5c2c8Array size: 1E0, 100000 loops, best of 3: 5.351 us/loopArray size: 1E1, 100000 loops, best of 3: 5.390 us/loopArray size: 1E2, 100000 loops, best of 3: 5.366 us/loopArray size: 1E3, 100000 loops, best of 3: 5.360 us/loopArray size: 1E4, 100000 loops, best of 3: 5.433 us/loopArray size: 1E5, 100000 loops, best of 3: 5.400 us/loopArray size: 1E6, 100000 loops, best of 3: 5.397 us/loopArray size: 1E7, 100000 loops, best of 3: 5.381 us/loopArray size: 1E8, 100000 loops, best of 3: 6.126 us/loop

由于缓冲区大小的限制,正在处理多个块,因此最后一个时间的上升幅度很小。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/517115.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号