我使用的是以下代码,使用的是python3.11:

import timeit

code_1 = """
initial_string = ''
for i in range(10000):
    initial_string = initial_string + 'x' + 'y'
"""

code_2 = """
initial_string = ''
for i in range(10000):
    initial_string += 'x' + 'y'
"""

time_1 = timeit.timeit(code_1, number=100)
time_2 = timeit.timeit(code_2, number=100)

print(time_1)
# 0.5770808999950532
print(time_2)
# 0.08363639999879524

为什么+=in this case更有效率? 据我所知,有相同数量的串联,执行顺序不会改变结果.

因为字符串是不变的,这并不是因为就地拼接,我发现关于字符串连接的唯一一件事是大约.join的效率,但我不想要最高效的,只要理解为什么+=似乎比=更高效.

使用此代码,表单之间的性能几乎相等:

import timeit

code_1 = """
initial_string = ''
for i in range(10000):
    initial_string = initial_string + 'x'
"""

code_2 = """
initial_string = ''
for i in range(10000):
    initial_string += 'x'
"""

time_1 = timeit.timeit(code_1, number=100)
time_2 = timeit.timeit(code_2, number=100)

print(time_1)
# 0.07953230000566691
print(time_2)
# 0.08027460001176223

我注意到了使用不同的Python版本('x' + 'y'形式)时的不同:

Python3.7到3.9:

print(time_1)
# ~0.6
print(time_2)
# ~0.3

Python3.10:

print(time_1)
# ~1.7
print(time_2)
# ~0.8

对比一下,Python3.11:

print(time_1)
# ~0.6
print(time_2)
# ~0.1

类似但没有回答问题:How is the s=s+c string concat optimization decided?

如果s是一个字符串,那么s=s+‘c’可能会修改该字符串,而t=s+‘c’则不能.但是,操作s+‘c’如何知道它处于哪种情况呢?

简而言之:优化在s = s + 'c'时发生,而不是在t = s + 'c'时,因为Python需要保持对第一个字符串的引用,并且不能就地连接.

在这里,我们总是使用简单赋值或扩充赋值来赋值给原始字符串,因此在这两种情况下都应该应用就地连接.

推荐答案

现在,CPython已经进行了一次优化,try 在可能的情况下就地执行字符串连接.在不同的Python版本之间,细节会有所不同,有时会有很大差异--例如,它不适用于全局变量on Python 3.11,并且它曾经特定于Python2上的字节串,但它特定于Python3上的Unicode字符串.

在Python3.10中,优化从unicode_concatenate开始,最终达到resize_compactresize_inplace内部的PyObject_Realloc,try 就地调整左操作数的大小.

在不同版本的Python中,关于优化的一个相当一致的事情是,只有当连接的左侧没有其他引用,或者唯一的引用是连接结果将被赋给的变量时,它才能起作用.在您的慢速 case 中:

initial_string = initial_string + 'x' + 'y'

initial_string + 'x'的lhs是initial_string,而not要将结果赋回initial_string-首先要将'y'与结果连接在一起.因此,优化不可能达到initial_string + 'x'.(不过,它在+ 'y'部分中起到了作用.)

对于您的其他情况,优化是有效的.例如,在

initial_string += 'x' + 'y'

不是先连接initial_string'x',然后再追加'y',而是连接'x''y',然后连接initial_string和结果.更改后的操作顺序意味着您将initial_string连接的结果重新赋值为initial_string,因此应用了优化.(此外,'x' + 'y'会不断折叠起来,这虽然有一些帮助,但不是造成性能差异的主要原因.)

Python相关问答推荐

ambda将时间戳与组内另一列的所有时间戳进行比较

Image Font生成带有条形码Code 128的条形码时出现枕头错误OSErsor:无法打开资源

如何使用entry.bind(FocusIn,self.Method_calling)用于使用网格/列表创建的收件箱

通过仅导入pandas来在for循环中进行多情节

如何使用Google Gemini API为单个提示生成多个响应?

Python会扔掉未使用的表情吗?

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

Pandas 都是(),但有一个门槛

发生异常:TclMessage命令名称无效.!listbox"

如何在虚拟Python环境中运行Python程序?

如何获得每个组的时间戳差异?

形状弃用警告与组合多边形和多边形如何解决

多处理队列在与Forking http.server一起使用时随机跳过项目

未调用自定义JSON编码器

python sklearn ValueError:使用序列设置数组元素

用SymPy在Python中求解指数函数

通过追加列表以极向聚合

删除特定列后的所有列

当输入是字典时,`pandas. concat`如何工作?

Python OPCUA,modbus通信代码运行3小时后出现RuntimeError