【问题标题】:Copy performance: list vs array复制性能:列表与数组
【发布时间】:2020-02-23 15:27:44
【问题描述】:

我正在优化一段代码,发现列表复制(浅)是瓶颈。

现在我很好奇:为什么复制列表比复制 8 字节的 array 慢得多?在我看来应该没有区别。在这两种情况下,它都应该只是memcpy(dst, src, sizeof(int64_t)*len(src)),因为指针的长度是 8 个字节。但显然 Python 所做的工作比我预期的要多。它与GC有某种关系吗?或者列表是否有可能实现为链表?

import array
import numpy as np
import timeit


n = 100*1000
lst = [i for i in range(n)]
arr = array.array('q', lst)
nmp = np.array(arr, dtype=np.int64)

assert(arr.itemsize == 8)

n_iter = 100000
print('=== copy() ===')
print('List of int:', timeit.timeit(stmt='lst.copy()', setup='from __main__ import lst', number=n_iter))
print('Array of 8-bytes:', timeit.timeit(stmt='arr.__copy__()', setup='from __main__ import arr', number=n_iter))
print('Numpy array of int64:', timeit.timeit(stmt='nmp.copy()', setup='from __main__ import nmp', number=n_iter))

结果:

=== copy() ===
List of int: 27.434935861998383
Array of 8-bytes: 2.6839109230022586
Numpy array of int64: 2.69919407800262

【问题讨论】:

    标签: python arrays performance numpy copy


    【解决方案1】:

    使用列表,它不仅仅是复制对对象的引用。它还增加了对象内的引用计数器。另外,这些不是缓存友好的,因为它们彼此之间不是很好地相邻,因为它们在对象内部(以及对象的其他数据)并且这些对象在某处 在堆上。另请参阅Why is copying a shuffled list much slower?(这里有更快的“未洗牌”案例,但那里的解释可能仍然有用)。

    【讨论】:

    • numpy 数组呢?
    • @AndreasK。通常 NumPy 数组不包含 Python 对象,但例如原始 64 位整数,如问题所示。所以他们没有这个额外的成本并且被复制得更快,如问题所示。这是否回答你的问题?你的个人资料看起来你比我更了解 NumPy,所以我不确定你为什么/问什么:-)
    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2012-05-31
    • 1970-01-01
    • 2010-09-16
    • 2011-08-19
    相关资源
    最近更新 更多