- 内容提要
- 前言
- 作者简介
- 封面简介
- 第1章 理解高性能 Python
- 第2章 通过性能分析找到瓶颈
- 2.1 高效地分析性能
- 2.2 Julia 集合的介绍
- 2.3 计算完整的 Julia 集合
- 2.4 计时的简单方法——打印和修饰
- 2.5 用 UNIX 的 time 命令进行简单的计时
- 2.6 使用 cProfile 模块
- 2.7 用 runsnakerun 对 cProfile 的输出进行可视化
- 2.8 用 line_profiler 进行逐行分析
- 2.9 用 memory_profiler 诊断内存的用量
- 2.10 用 heapy 调查堆上的对象
- 2.11 用 dowser 实时画出变量的实例
- 2.12 用 dis 模块检查 CPython 字节码
- 2.13 在优化期间进行单元测试保持代码的正确性
- 2.14 确保性能分析成功的策略
- 2.15 小结
- 第3章 列表和元组
- 第4章 字典和集合
- 第5章 迭代器和生成器
- 第6章 矩阵和矢量计算
- 第7章 编译成 C
- 第8章 并发
- 第9章 multiprocessing 模块
- 第10章 集群和工作队列
- 第11章 使用更少的 RAM
- 第12章 现场教训
11.3 字节和 Unicode 的对比
转换到Python 3.3+的一个令人信服的理由就是它对Unicode对象的存储明显要比在Python 2.7中少。如果你主要处理许多字符串,并且它们吃掉了很多RAM,一定要考虑转移到Python 3.3中去。这样你就绝对免费地得到了对RAM的节省。
在例11-7中,我们可以看到100000000个字符的序列被构建成字符集合(这与在Python 2.7中的常规的str相同)以及被构建成Unicode的对象。Unicode变体占用了多达4倍的RAM,每一个Unicode字符耗费了相同的更高的代价,而不管表示底层数据所需的字节的数量是多少。
例11-7 Unicode对象在Python 2.7中是代价高昂的
In [1]: %load_ext memory_profiler In [2]: %memit b"a" * int(1e8) peak memory: 100.98 MiB, increment: 80.97 MiB In [3]: %memit u"a" * int(1e8) peak memory: 380.98 MiB, increment: 360.92 MiB
Unicode对象的UTF-8编码为每个ASCII字符使用一个字节,而为更少见到的字符使用了更多的字节。Python 2.7为每一个Unicode字符使用了相同数量的字节数,而不管字符的出现率。如果你对Unicode编码和Unicode对象的对比没有把握,那么请去看看Net Batchelder的“实践Unicode,或者是,我该如何结束痛苦?”
从Python 3.3开始,多亏了PEP 393,我们具有了灵活的Unicode表示。它通过观察字符串中的字符范围,并且尽可能使用更少的字节数来表示更低阶的字符的方式来工作。
在例11-8中,你可以见到字节的开销和ASCII字符的Unicode版本的开销是一样的,并且使用了非ASCII的字符(sigma)仅仅翻倍地使用了内存——这还是比Python 2.7中的境遇要更好。
例11-8 Unicode对象在Python 3.3+中要远远更低廉
Python 3.3.2+ (default, Oct 9 2013, 14:50:09) IPython 1.2.0 -- An enhanced Interactive Python. ... In [1]: %load_ext memory_profiler In [2]: %memit b"a" * int(1e8) peak memory: 91.77 MiB, increment: 71.41 MiB In [3]: %memit u"a" * int(1e8) peak memory: 91.54 MiB, increment: 70.98 MiB In [4]: %memit u"Σ" * int(1e8) peak memory: 174.72 MiB, increment: 153.76 MiB
在Python 3.3默认Unicode对象的前提下,如果你在许多字符串数据上工作,你几乎肯定会受益于这个升级。缺少低廉的字符串存储对一些人来说是在早期Python 3.1期间遇到的一个障碍,但是现在随着PEP 393,这完全不是一个问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论