【问题标题】:Difference of "+=" operator and string concatenation in memory?内存中“+=”运算符和字符串连接的区别?
【发布时间】:2021-06-06 13:04:55
【问题描述】:

在我读的一本书中,我了解到标准的字符串连接可能很难记忆,因为它每次都会复制字符串本身并添加新值。

message = message + chr(codeNum)

我想知道 += 运算符是否相同。

message += chr(codeNum)

我在其他语言上看到了一些类似的主题,但我的问题主要是关于 Python 的。你能在这方面提供一些知识吗?

【问题讨论】:

  • Python 字符串是不可变的,因此加法操作是二进制还是内联都没有关系——无论哪种方式,结果都是不同于原始字符串的结果,因此将创建一个包含所有字符串的新字符串相关的开销。
  • 发生的情况是字符串是不可变的,一旦它绑定到一个变量就不可能改变它。当一个字符串被“修改”时,它实际上是一个重新分配给同一个变量的新字符串。所以我会说使用什么运算符进行连接没有显着差异。
  • CPython 实现中有一个奇怪且有些脆弱的优化,它试图可变地执行此操作,但优化并不关心您使用+ 还是+=
  • (不要依赖奇怪的优化。建立一个要连接的东西列表并使用''.join 一次性连接所有内容。这适用于所有 Python 实现,并且保证不会降级为二次性能。)
  • 在某些语言中,通过重复连接构建长字符串是一种习惯用法,就像您在示例中所做的那样。因为在 Python 中这样做是低效的,所以习惯用法是组装一个短字符串的临时列表(扩展一个列表比重新分配一个字符串更有效)并通过一次调用 join() 创建一个长字符串,当列表已完成。

标签: python memory memory-management concatenation accumulator


【解决方案1】:

在 python 中是的, message = message + chr(codeNum) 和 消息 += chr(codeNum) 是一回事。 基本上 += 运算符所做的是将 LHS 和 RHS 相加并将值存储在 LHS 中。 希望它能澄清你的疑问。

【讨论】:

    【解决方案2】:

    你可以通过使用 timeit 模块来解决这个问题,看起来它们确实是等效的方法:

    >>> s = timeit.Timer(stmt="s1 = 'str1';s2 = 'str2';s1 = s1 + s2")
    >>> s.timeit()
    0.04924579999999423
    
    >>> s3 = timeit.Timer(stmt="s1 = 'str1';s2 = 'str2';s1 += s2")
    >>> s3.timeit()
    0.0429421999999704
    

    【讨论】:

      【解决方案3】:

      没有区别。这可以通过简单的基准测试来证明。

      1000000 次迭代的 50 次调用。

      import timeit
      if __name__ == '__main__':
          for i in range(50):
              print(timeit.timeit(stmt='msg = msg + chr(33)', setup='msg=""'))
      

      平均。 0.1719

      import timeit
      if __name__ == '__main__':
          for i in range(50):
              print(timeit.timeit(stmt='msg += char(33)', setup='msg=""'))
      

      平均。 0.1748

      【讨论】:

        猜你喜欢
        • 2018-11-10
        • 2017-08-08
        • 2020-09-05
        • 2012-10-10
        • 2015-01-11
        • 1970-01-01
        • 2019-01-12
        • 2010-09-08
        • 2014-02-27
        相关资源
        最近更新 更多