Python 进阶
Python 协程实现原理
dict 和 set 实现原理
Python 线程安全
Python 抽象语法树(AST)
Python 日志输出
Python 扩展入门(一)
Python 程序执行原理
Python 垃圾回收
Python 动态创建类
检查工具
PyFrameObject
yield 生成器工作原理
dict 设计与实现
Python 性能分析原理
PyCodeObject
Python 弱引用
Python 性能分析原理(二)
Python 源码分析(一)
Python Annotated
Python 依赖注入
python freelist
python代码编译成pyc
Python mmap 内存映射文件
Python值得学习的内容
async Future 对象
asyncio loop的实现
asyncio.sleep 的实现
asyncio 原理
Python 代码加密
Python Token类型
Python 扩展入门(二)
Python 性能优化
本文档使用 MrDoc 发布
-
+
首页
Python mmap 内存映射文件
### 计算机内存分类 - 物理内存 - 虚拟内存 - 共享内存 ### 深入了解文件IO 常规的文件IO过程: 1. 通过系统调用将控制权转移到内核; 2. 与文件所在的物理磁盘交互; 3. 将数据复制到用户空间和内核空间之间的缓冲区中; 以下是一个常规的文件IO示例: ``` def regular_io(filename): with open(filename, mode="r", encoding="utf8") as file_obj: text = file_obj.read() print(text) ``` 如果在运行时有足够的可用空间,此代码会将整个文件读入物理内存,并将其打印到屏幕上。 实际上,调用`read()` 通知操作系统执行许多复杂的工作。幸运的是,操作系统提供了一种方法,可以通过系统调用从程序中抽象出每个硬件设备的具体细节。每个操作系统都会以不同的方式实现此功能,但至少`read()`必须执行多个系统调用才能从文件中读取数据。 所有对物理硬件的访问都必须发生在称为`内核空间`的受保护环境中。系统调用是操作系统提供的API,允许程序从用户空间转到内核空间,在内核空间管理物理硬件的低级别详细信息。 对于`read()`,操作系统需要多次系统调用来与物理存储设备交互才能返回数据。 除了系统调用之外,在数据完全返回到您的程序之前,对`read()`的调用还涉及在多个数据缓冲区之间进行大量的不必要的数据复制。 通常,这一切都发生得如此之快,以至于不会引起注意。但是所有这些层都会增加延迟并会减慢您的程序速度。 ### 内存映射的优化 减少开销的一种方法是使用内存映射文件。您可以将内存映射描述为一个过程,在该过程中,读写操作会跳过上面提到的许多层,并将请求的数据直接映射到内存中。 内存映射文件方法为了速度牺牲了内存空间,这在传统上称为`时空权衡`。但是,内存映射不必使用比传统方法更多的内存,操作系统非常聪明,它将根据请求延迟加载数据,类似于Python 生成器的工作方式。 此外,借助`虚拟内存`,您可以加载比物理内存大的文件。但是,当文件没有足够的物理内存时,您不会看到内存映射带来的巨大性能改进,因为操作系统将使用较慢的物理存储介质(如固态磁盘)来模拟它缺少的物理内存。 使用内存映射文件改写上面的读取文件操作: ``` import mmap def mmap_io(filename): with open(filename, mode="r", encoding="utf8") as file_obj: with mmap.mmap(file_obj.fileno(), length=0, access=mmap.ACCESS_READ) as mmap_obj: text = mmap_obj.read() print(text) ``` ### 性能影响 内存映射方法比典型的文件 I/O 稍微复杂一些,因为它需要创建另一个对象。然而,在读取只有几兆字节的文件时,这种微小的变化可以带来巨大的性能优势。这是阅读著名小说《堂吉诃德的历史》的原始文本的比较,大约2.4兆字节: ``` >>> import timeit >>> timeit.repeat( "regular_io(filename)", repeat=3, number=1, setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( "mmap_io(filename)", repeat=3, number=1, setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] ``` 如您所见: - 常规方法需要 0.02 秒; - 内存映射文件方法只需要 0.005 秒; 在读取较大的文件时,这种性能改进可能会更大。 ### 结论 内存映射是 Python 程序通过mmap模块使用的文件IO的替代方法。内存映射使用较低级别的操作系统API将文件内容直接存储在物理内存中。这种方法通常会提高IO性能,因为它避免了许多昂贵的系统调用并减少了昂贵的数据缓冲区传输。 ### 参考 > [Python mmap:使用内存映射改进文件 I/O](https://bbs.huaweicloud.com/blogs/detail/313265) > [Python mmap: Improved File I/O With Memory Mapping](https://realpython.com/python-mmap/)
gaojian
2024年4月6日 18:29
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码