为什么加入numpy数组比列表需要更长的时间?

时间:2018-05-18 14:14:40

标签: python numpy optimization concatenation timing

我在一系列角色的随机样本中发现了这一点。如果它属于其他地方,请告诉我。

如果我生成1000个字符的列表:

my_list = random.choices('abc', k=1000)

和一个1000个字符的numpy数组:

my_array = np.array(my_list)

然后将它们连接成一个长字符串并计时,我得到:

''.join(my_list)  # vanilla Python list
# 7.69 µs ± 103 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

''.join(my_array)  # numpy array
# 257 µs ± 3.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

为什么运行时间存在巨大差异?

我的想法

我的第一个想法是str.join方法在加入之前将numpy数组转换为列表。没有这样的运气。如果我把我的numpy数组转换成一个列表,我就不会在两个操作之间找到差别。 ndarray.tolist()非常快!

my_array.tolist()
11.6 µs ± 87 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

所以我认为str.join只是针对Python列表进行了超级优化,而不是针对numpy数组?这看起来很奇怪,因为numpy数组和操作通常都经过了非常优化,并且通常比等效的vanilla Python实现快得多(参见下面的示例)。

我不确定在哪里找到str.join的实际实现,所以我无法使用源代码(Luke)。

除此之外:使用numpy生成随机字符

如果我用numpy生成我的随机字符:

my_array = np.random.choice([char for char in 'abc'], size=1000, replace=True)
# 29.8 µs ± 2.33 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

并将此运行时间与random.choices进行比较,我得到的numpy比random.choices快一个数量级,而其他来自随机的选项似乎仍然较慢(more details here) :

my_list = random.choices('abc', k=1000)
# 276 µs ± 6.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

这意味着如果我为我的应用程序一次性生成并加入我的列表,这两种方法的速度大致相同。但它让我想知道为什么 numpy一旦我将联接操作带入混合中就无法保持领先。

0 个答案:

没有答案