我有一个问题,np.reshape
是一个瓶颈。我想知道在什么情况下它是快的,什么时候它是慢的。下面的代码解释了我的问题:
import time
import numpy as np
n = 28
# perm = np.arange(n)[::-1] #very slow
# perm = (np.arange(n)+15)%n #still slow
perm = (np.arange(n)+1)%n #fast
test = np.arange(2**n, dtype = np.complex64)
start_time = time.time()
test = test.reshape(n*[2])
test = np.moveaxis(test, np.arange(n), perm)
test = test.reshape(2**n)
print(time.time()-start_time)
有人知道在哪里可以找到整形操作的C源代码吗?
编辑
它似乎取决于排列数组到恒等式之间的距离,即。
distance = np.sum(np.abs(perm-np.arange(n)))
我已经执行了一些基准测试,loglog(运行时)似乎与距离呈线性相关。benchmark plot
1条答案
按热度按时间pzfprimi1#
用你的
n=28
我得到的时间(与你的结果相似):3个排列顺序为:
反转的:
两块交换
第一个轴移动到末端:
最后一个
reshape
就是np.ravel()
。所有情况下都会在
moveaxis
中产生view
,然后在ravel
中产生copy
。4例病例的步幅为:
这些都是相同的步长,但只是重新排序的预测烫发。
解析
reshape/ravel
必须采用重新排序的版本,并按照步幅指定的顺序遍历值,首先迭代最小的值。其他对处理器缓存等有更好理解的人可能能够更好地解释这一点,但是不同的顺序可能需要不同的时间。该大小足够大,以至于内存访问时间(包括cash和页面)可能会有所不同。总而言之,我不认为这是
np.reshape
做什么的问题,而更多的是以各种顺序遍历内存需要多长时间的问题。正如我的评论所示,我首先认为最大的区别是在视图与副本。但现在我发现所有案子都有副本。只是有些维度混合需要比其他维度更长的时间来遍历。您必须比
reshape
函数本身更深入地挖掘才能理解发生了什么。它涉及多维数组的最内部工作,特别是strides
的含义和使用。如果你不用这么大的
n
,我的演示会更紧凑。我首先尝试了n=5
,但ravel
步骤比moveaxis
步骤花费的时间更少。我怀疑有一个中等大小的烫发顺序没有太大的区别。忽略缓存和分页问题,跨越式多维数组应该能够在大约相等的时间内访问任何顺序的维度-例如,如果ravel时间是毫秒级。