mmap不是万能加速器,仅在随机查找、多进程共享或反复回溯时优于open();顺序逐行处理应优先用for line in open(),更稳更省更安全。

mmap 不是万能加速器,它只在特定场景下比 open() 快——比如随机查找、多进程共享、或需反复回溯。如果你只是顺序读一行处理一行,用 for line in open() 更稳、更省、更不易出错。
什么时候该用 mmap?看三个硬条件
别被“内存映射”四个字唬住,先确认你是否真的需要它:
- 你要搜一个关键词(比如
b"500"),且文件远大于内存(10GB 日志里找几处错误) - 你要反复跳转访问不同位置(比如解析固定偏移的二进制协议头)
- 多个进程要同时读同一份只读文件,且希望共享内核页缓存
不满足以上任一条件,mmap 很可能让你 RSS 占用更高、swap 更频繁,甚至变慢。
mmap 必须搭配 r+b 模式和 fileno()
常见报错 ValueError: cannot mmap an empty file 或 OSError: [Errno 22] Invalid argument,基本都卡在这步:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 文件必须用
'r+b'打开(即使只读也要可写权限,否则fileno()在某些系统上不可用) - 不能用
io.TextIOWrapper包装过的文件对象,必须是原始open()返回的 file object -
mmap.mmap(f.fileno(), 0)中长度传0表示映射全部,但若文件为空会失败;可先os.stat(f.name).st_size判断
搜索中文或带空格关键词时,bytes 是唯一合法输入
这是最常踩的坑:写 re.finditer("登录失败", mm) 直接报 TypeError。因为 mmap 对象是 bytes-like,正则也必须用 bytes 模式:
- 中文关键词必须用
b"\xe7\x99\xbb\xe5\xbd\x95\xe5\xa4\xb1\xe8\xb4\xa5"(UTF-8 编码)或"登录失败".encode("utf-8"),不能用字符串字面量 - 空格、制表符、换行符都要显式写出
b" \t\n",不能依赖str.split()那套逻辑 - 跨行匹配天然支持(
mmap是连续字节流),但要注意换行符是b"\n"还是b"\r\n",不会自动归一
mmap 不省物理内存,只省“拷贝”
很多人误以为用了 mmap 就不占内存了。事实是:
- 它不减少 RSS(实际物理内存占用),只是把“从磁盘读→内核缓存→用户空间”的两次拷贝,变成一次映射
- 真正省的是 CPU 时间和上下文切换开销,不是内存容量
- 如果同时映射多个大文件,或在小内存机器上映射超大文件,反而容易触发 swap,响应变卡
真正压内存的方案,还是按块读(f.read(65536))或生成器逐行(for line in f)——mmap 解决的是“快”,不是“轻”。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










