为什么在python中为一个变量分配一个连接字符串时会这么慢?

2024-10-01 22:33:31 发布

您现在位置:Python中文网/ 问答频道 /正文

如果它只是字符串的串联,那么它将立即结束。在

test_str = "abcdefghijklmn123456789"
str1 = ""
str2 = ""

start = time.time()
for i in range(1, 100001):

    str1 = str1 + test_str
    str2 = str2 + test_str

    if i % 20000 == 0:
        print("time(sec) => {}".format(time.time() - start))
        start = time.time()

恒定处理时间

^{pr2}$

令人费解的是,给另一个变量分配一个串联字符串会使过程变得越来越慢。在

test_str = "abcdefghijklmn123456789"
str1 = ""
str2 = ""

start = time.time()
for i in range(1, 100001):

    str1 = str1 + test_str
    # str2 = str2 + test_str
    # ↓
    str2 = str1

    if i % 20000 == 0:
        print("time(sec) => {}".format(time.time() - start))
        start = time.time()

处理时间将延迟。在

time(sec) => 0.36466407775878906
time(sec) => 1.105351209640503
time(sec) => 2.6467738151550293
time(sec) => 5.891657829284668
time(sec) => 9.266698360443115

Python2和Python3的结果是一样的。在


Tags: 字符串intestformatforiftimerange
1条回答
网友
1楼 · 发布于 2024-10-01 22:33:31

一般来说,Python语言标准在这里不作任何保证;事实上,正如定义的那样,字符串是不可变的,您所做的事情应该以任何方式咬到您,就像您编写了一个Schlemiel the Painter's algorithm的形式一样。在

但是在第一种情况下,作为实现细节,CPython(引用解释器)将帮助您解决问题,并在一些相当具体的条件下连接一个字符串(技术上违反了不变性保证),这些条件允许它遵守不变性规则的精神。最重要的条件是被连接的字符串必须只在一个地方被引用(如果不是这样,另一个引用就会改变,这违反了str不可变的外观)。通过在每次连接后分配str2 = str1,可以保证在连接时有两个引用,因此每次连接都必须生成一个新的str,以保持字符串明显的不变性。这意味着更多的内存分配和释放,更多(并且逐渐增加)内存拷贝,等等

请注意,在PEP 8, the Python style guide中不鼓励依赖此优化:

  • Code should be written in a way that does not disadvantage other implementations of Python (PyPy, Jython, IronPython, Cython, Psyco, and such).

    For example, do not rely on CPython's efficient implementation of in-place string concatenation for statements in the form a += b or a = a + b. This optimization is fragile even in CPython (it only works for some types) and isn't present at all in implementations that don't use refcounting. In performance sensitive parts of the library, the ''.join() form should be used instead. This will ensure that concatenation occurs in linear time across various implementations.

关于“只适用于某些类型”的注释很重要。此优化仅适用于str;在python2中,它不适用于unicode(尽管python3的str是基于python2的unicode的实现的),而在python3中,它不适用于bytes(这与python2的str非常相似)。在

相关问题 更多 >

    热门问题