为何Python内置str.join()方法性能未优于+=?附NumPy测试案例
NumPy数组转二进制字符串的性能疑问及解析
首先生成测试用的NumPy数组:
binary_str = np.random.randint(2, size=1000000, dtype='int')
两种字符串拼接方法
方法1:利用join一次性拼接
binary_str = ''.join(binary_str.astype(str))
方法2:循环逐个拼接
s = '' for c in binary_str: s += str(c)
性能疑问
按常规认知,方法1应该比方法2快很多——join是一次性完成字符串拼接,避免了循环中反复内存分配和复制的开销(理论时间复杂度O(n));而方法2每次循环都要创建新字符串并复制,理论时间复杂度为O(n²)。但在Python 3.10.4中用time.time或timeit测试时,两种方法耗时几乎相同,甚至方法1耗时更长,这是什么原因?
原因解析
这个反常现象是NumPy的迭代机制和**astype(str)的额外开销**共同导致的:
- 方法1中,
binary_str.astype(str)会先把整个NumPy数组转换成字符串类型的数组,这个过程本身就有不小的开销;而且直接对NumPy字符串数组使用join时,底层还是会逐个迭代数组元素,并没有真正发挥join的高效批量拼接优势。 - Python 3对字符串拼接做了针对性优化,
s += str(c)的底层实现不再是每次创建新字符串,而是会复用内存空间,实际时间复杂度接近O(n),抵消了循环的部分劣势。
如果先将转换后的字符串数组转成Python原生列表,再调用join,就能体现出两者显著的性能差异:
binary_str = ''.join(binary_str.astype(str).tolist())
内容的提问来源于stack exchange,提问作者li_jessen
相关产品推荐
相关产品推荐

