加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 为什么可变字符串比不可变字符串慢?

发布时间:2020-12-20 13:06:02 所属栏目:Python 来源:网络整理
导读:为什么可变字符串比不可变字符串慢? 编辑: import UserString... def test():... s = UserString.MutableString('Python')... for i in range(3):... s[0] = 'a'... ... if __name__=='__main__':... from timeit import Timer... t = Timer("test()","fro
为什么可变字符串比不可变字符串慢?

编辑:

>>> import UserString
... def test():
...     s = UserString.MutableString('Python')
...     for i in range(3):
...         s[0] = 'a'
... 
... if __name__=='__main__':
...     from timeit import Timer
...     t = Timer("test()","from __main__ import test")
...     print t.timeit()
13.5236170292



>>> import UserString
... def test():
...     s = UserString.MutableString('Python')
...     s = 'abcd'
...     for i in range(3):
...         s = 'a' + s[1:]
... 
... if __name__=='__main__':
...     from timeit import Timer
...     t = Timer("test()","from __main__ import test")
...     print t.timeit()
6.24725079536


>>> import UserString
... def test():
...     s = UserString.MutableString('Python')
...     for i in range(3):
...         s = 'a' + s[1:]
... 
... if __name__=='__main__':
...     from timeit import Timer
...     t = Timer("test()","from __main__ import test")
...     print t.timeit()
38.6385951042

我认为很明显为什么我在第二次测试中放入s = UserString.MutableString(‘Python’).

解决方法

在一种假设的语言中,它提供了可变的和不可变的,或者是等价的字符串类型(我不能真正想到一个 – 例如,Python和Java都只有不可变的字符串,以及其他通过突变来增加间接性的方法因此当然可以减慢一些事情;-),没有任何性能差异的真正原因 – 例如,在C中,可互换地使用std :: string或const std :: string我会期望导致没有性能差异(诚然,编译器可能能够通过计算不变性来更好地使用后者来优化代码,但我不知道任何真正的代码执行这样的理论上可能的优化;-).

拥有不可变字符串可能并确实允许在Java和Python中进行非常大量的优化.例如,如果字符串被散列,则哈希值可以被缓存,并且永远不必重新计算(因为字符串不能更改) – 这在使用散列字符串的Python中尤其重要(对于集合中的查找)和词典)如此奢华甚至“幕后”.新鲜的副本永远不需要“以防万一”,前一个副本在此期间发生了变化 – 只要需要该字符串,就可以系统地分发对单个副本的引用. Python还大量使用(某些)字符串的“实习”,可能允许进行常数时间比较和许多其他类似的快速操作 – 将其视为一种更多方式,一种更先进的方法,以利用字符串的不变性缓存更多经常对它们执行的操作的结果.

当然,这并不是说给定的编译器会利用所有可能的优化.例如,当请求一个字符串切片时,不需要创建一个新对象并复制数据 – 新切片可能引用具有偏移量(以及独立存储长度)的旧切片,可能对于大字符串的一个很好的优化,其中采取了许多切片. Python没有这样做,因为除非在内存管理中特别小心,否则这可能很容易导致“大”字符串在实际只需要一小部分时保留在内存中 – 但这是一个权衡不同的实现可能肯定会选择执行(具有额外内存管理的负担,确保 – 对于所讨论的假设语言更复杂,更难以调试的编译器和运行时代码).

我只是在这里摸索 – 如果在可变和不可变版本中可以存在可互换的字符串类型,那么很多这些优点将很难保持(我怀疑是为什么,至少就我目前的知识而言,C编译器实际上并不打扰这种优化,尽管通常非常注重性能).但是通过仅提供不可变的字符串作为原始的基本数据类型(因此当你真的需要一个可变的字符时隐含地接受一些缺点;-),诸如Java和Python之类的语言可以明显地获得各种优势 – 性能问题只是其中的一组(例如,Python只允许不可变基元类型可选择的选择不是以性能为中心的设计决策 – 它更多地是关于集合和字典行为的清晰度和可预测性! – ).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读