You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字符串拼接:为何join在循环中比+=慢?用法是否有误?

字符串拼接:+= vs ''.join()的性能疑问

我了解到CPython对a = a + b或a += b形式的字符串拼接有原地无拷贝优化,同时PEP8建议不要依赖该优化,推荐在性能敏感场景使用''.join()以保证多Python实现下的线性时间性能。我尝试用a = ''.join([a, b, c])替代a += b + c,但测试发现循环中join的性能远低于+=,测试代码及结果如下:

测试代码

import os
import time

if __name__ == "__main__":
    start_time = time.time()
    print("begin: %s " % (start_time))
    s = ""
    for i in range(100000):
        s = s + str(i) + '3'
    time1 = time.time()
    print("end loop1: %s " % (time1 - start_time))

    s2 = ""
    for i in range(100000):
        s2 += str(i) + '3'

    time2 = time.time()
    print("end loop2: %s " % (time2 - time1))

    s3 = ""
    for i in range(100000):
        s3 = ''.join([s3, str(i), '3'])

    time3 = time.time()
    print("end loop3: %s " % (time3 - time2))

测试结果

~/testdir$ python --version
Python 3.10.6
~/testdir$ python concatenate.py 
begin: 1675268345.0761461 
end loop1: 3.9019 
end loop2: 0.0260 
end loop3: 0.9289 

请问我的join用法是否有误?


解答

你的join用法确实错了,这才导致性能远不如+=。

问题出在哪?

''.join()的核心优势是一次性计算所有待拼接片段的总长度,分配一次内存后完成所有内容拷贝,时间复杂度是O(n)。但你在循环里每次调用''.join([s3, str(i), '3']),相当于每次都要把之前已经拼接好的s3重新拷贝一遍——和未优化的a = a + b一样,时间复杂度变成了O(n²),自然性能拉胯。

正确的join用法

应该先把所有要拼接的片段收集到一个列表里,最后只调用一次''.join():

import time

if __name__ == "__main__":
    start_time = time.time()
    print(f"begin: {start_time} ")
    
    # 原s = s + ...
    s = ""
    for i in range(100000):
        s = s + str(i) + '3'
    time1 = time.time()
    print(f"end loop1 (+): {time1 - start_time:.4f} ")
    
    # 原s2 += ...
    s2 = ""
    for i in range(100000):
        s2 += str(i) + '3'
    time2 = time.time()
    print(f"end loop2 (+=): {time2 - time1:.4f} ")
    
    # 错误的join用法
    s3 = ""
    for i in range(100000):
        s3 = ''.join([s3, str(i), '3'])
    time3 = time.time()
    print(f"end loop3 (错误join): {time3 - time2:.4f} ")
    
    # 正确的join用法
    parts = []
    for i in range(100000):
        parts.append(str(i) + '3')
    s4 = ''.join(parts)
    time4 = time.time()
    print(f"end loop4 (正确join): {time4 - time3:.4f} ")

预期结果

运行后你会发现,正确的join用法性能和+=接近甚至持平(不同Python版本可能有细微差异),因为它真正发挥了join的线性时间优势。

额外说明

  • CPython的+=优化是特定实现细节:字符串本身不可变,但当变量是该字符串的唯一引用时,CPython会尝试原地扩容,避免重复拷贝。但其他Python实现(如PyPy、Jython)不一定支持这个优化。
  • PEP8推荐''.join()的原因是它在所有Python实现中都能保证线性时间性能,代码兼容性更强;如果你的代码只针对CPython,循环里用+=也能获得很好的性能。

内容的提问来源于stack exchange,提问作者Étienne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:45:36