当前位置: 首页 > 面试题库 >

为什么''.join()在Python中比+ =快?

漆雕亮
2023-03-14
问题内容

我可以在网上(在Stack
Overflow上以及其他方面)找到大量有关使用Python++=在Python中进行连接是一种非常低效且不好的做法的信息。

我似乎找不到为什么+=效率如此低下。在这里没有提到“在某些情况下已针对20%的改进进行了优化”(仍然不清楚这些情况是什么),我找不到任何其他信息。

''.join()比其他Python串联方法更好的技术水平上发生了什么?


问题答案:

假设您有这段代码可以从三个字符串中构建一个字符串:

x = 'foo'
x += 'bar'  # 'foobar'
x += 'baz'  # 'foobarbaz'

在这种情况下,Python首先需要分配和创建,'foobar'然后才能分配和创建'foobarbaz'

因此,对于每个+=被调用的字符串,其全部内容以及所添加的内容都需要复制到一个全新的内存缓冲区中。换句话说,如果您N要连接字符串,则需要分配大约N临时字符串,并且第一个子字符串将被复制大约N次。最后一个子字符串仅被复制一次,但是平均而言,每个子字符串被复制~N/2一次。

使用.join,Python可以起到许多技巧,因为不需要创建中间字符串。CPython计算出它需要多少内存,然后分配一个正确大小的缓冲区。最后,它将每个片段复制到新缓冲区中,这意味着每个片段仅被复制一次。

+=在某些情况下,还有其他可行的方法可能会导致更好的性能。例如,内部字符串表示形式实际上是arope还是运行时足够聪明,以某种方式找出临时字符串对程序没有用,并对其进行优化。

但是,CPython当然 不能
可靠地进行这些优化尽管可能在[某些极端情况下,并且由于它是使用中最常见的实现,因此许多最佳实践都基于对CPython有效的方法。拥有一套标准化的规范也使其他实施更容易集中精力进行优化。



 类似资料:
  • 为什么比快?我使用的是CPython 3.5.2。 我试着改变我提升的幂,看看它是怎么做的,例如,如果我提升x的10或16的幂,它会从30跳到35,但如果我提升10.0作为浮动,它只是在24.1~4左右移动。 我想这和浮点转换和2次方有关,但我真的不知道。

  • 问题内容: 下面是分别用和编码的简单过程(对于那些对此过程感到好奇的人,这是针对Euler项目5号问题的解决方案)。 我的问题是,下面的代码仅需9秒即可迭代,而代码完成则需要283秒(确切地说,在Python 3.4.3-64位上为283秒,在Python 2.7.9-32位上为329秒)。 到目前为止,我已经编码的两种类似的过程和与执行时间的差异,具有可比性。但是,这次,经过的时间之间存在极大的

  • 问题内容: 在优化代码时,我意识到了以下几点: 并且: 我认为它与在C中实现python的方式有关,但我想知道是否有人愿意解释为什么会这样? 问题答案: 结果的(有些出乎意料的原因)是Python似乎折叠了涉及浮点乘法和幂运算而不是除法的常量表达式。完全是另一种野兽,因为没有字节码,并且涉及函数调用。 在Python 2.6.5上,以下代码: 编译为以下字节码: 如您所见,乘法和乘幂根本不需要时间

  • 问题内容: 我刚刚读过“深入Python”,“元组比列表快”。 元组是不可变的,列表是可变的,但是我不太明白为什么元组更快。 有人对此进行过性能测试吗? 问题答案: 所报告的“构建速度”比率仅适用于 常量 元组(其项目由文字表示的元组)。仔细观察(并在您的机器上重复-您只需要在shell /命令窗口中键入命令即可!)…: 我没有在3.0上进行测量,因为我当然没有它-它已经完全过时了,绝对没有理由保

  • 问题内容: 我正在研究python线程并遇到了。 作者告诉我,如果线程处于守护程序模式,那么我需要使用它,以便线程可以在主线程终止之前完成自身。 但我一直在使用也没见他即使不 示例代码是这个 我不知道这是什么用途,因为它不是守护程序,即使删除它也看不到任何变化 问题答案: 展示这种机制的技术有些笨拙:大概是由主线程调用的。也可以由另一个线程调用它,但是会不必要地使该图复杂化。 -调用应该放在主线程

  • 问题内容: 之间有什么区别? 和: 我可以互换使用吗? 问题答案: MySQL在和之间没有区别。他们是一样的。 在两个示例中,子句 将任何类型的联接转换为内部联接。表达此查询的标准方式是