概述
我在Ipython中的计时是(使用更简单的timeit接口):In [57]: timeit np.zeros_like(x)
1 loops, best of 3: 420 ms per loop
In [58]: timeit np.zeros((12488, 7588, 3), np.uint8)
100000 loops, best of 3: 15.1 µs per loop
当我使用IPython(np.zeros_like??)查看代码时,我看到:res = empty_like(a, dtype=dtype, order=order, subok=subok)
multiarray.copyto(res, 0, casting='unsafe')
而np.zeros是纯黑盒编译的代码。
empty的计时为:In [63]: timeit np.empty_like(x)
100000 loops, best of 3: 13.6 µs per loop
In [64]: timeit np.empty((12488, 7588, 3), np.uint8)
100000 loops, best of 3: 14.9 µs per loop
所以zeros_like中的额外时间是copy。
在我的测试中,赋值时间(x[]=1)的差异可以忽略不计。
我猜zeros、ones、empty都是早期编译的产物。empty_like是为了方便起见添加的,只需从输入中绘制形状和类型信息。zeros_like编写时更注重易于编程维护(重用empty_like),而不是速度。
np.ones和np.full也使用np.empty ... copyto序列,并显示类似的计时。
https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/ctors.c-用于zeros和empty的源。两者都调用PyArray_NewFromDescr_int,但一个最终使用npy_alloc_cache_zero,另一个使用npy_alloc_cache。
npy_alloc_cache在alloc.c调用alloc。npy_alloc_cache_zero调用npy_alloc_cache,然后是memset。alloc.c中的代码与线程选项进一步混淆。
但是,对于缓存和垃圾收集,我想知道calloc/memset区别是否适用。
这个带有memory_profile包的简单测试支持这样一种说法,即zeros和empty动态分配内存,而zeros_like预先分配所有内容:N = (1000, 1000)
M = (slice(None, 500, None), slice(500, None, None))
Line # Mem usage Increment Line Contents
================================================
2 17.699 MiB 0.000 MiB @profile
3 def test1(N, M):
4 17.699 MiB 0.000 MiB print(N, M)
5 17.699 MiB 0.000 MiB x = np.zeros(N) # no memory jump
6 17.699 MiB 0.000 MiB y = np.empty(N)
7 25.230 MiB 7.531 MiB z = np.zeros_like(x) # initial jump
8 29.098 MiB 3.867 MiB x[M] = 1 # jump on usage
9 32.965 MiB 3.867 MiB y[M] = 1
10 32.965 MiB 0.000 MiB z[M] = 1
11 32.965 MiB 0.000 MiB return x,y,z
最后
以上就是笑点低机器猫为你收集整理的python中numpy zeros_为什么numpy.zeros和numpy.zeros的性能不同?的全部内容,希望文章能够帮你解决python中numpy zeros_为什么numpy.zeros和numpy.zeros的性能不同?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复