返回介绍

11.3 字节和 Unicode 的对比

发布于 2024-01-25 21:44:08 字数 1459 浏览 0 评论 0 收藏 0

转换到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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文