Python中批量打开13K+JSON文件速度慢的优化方案咨询
优化单线程大数量JSON文件读取的IO瓶颈
针对你遇到的13000+ JSON文件读取时的IO瓶颈,以下几个不合并文件、不使用并行化的优化方向可以直接落地:
1. 调大文件缓冲区并采用二进制模式读取
- 操作方式:打开文件时指定
buffering参数为较大值(如1024*1024即1MB),同时用rb二进制模式打开,一次性读取全部字节内容后再用JSON库解析。 - 核心原理:默认文本模式的缓冲区偏小,会触发频繁的系统IO调用;二进制模式跳过编码转换开销,大缓冲区能大幅减少内核态与用户态的切换次数。
- 示例代码:
import ujson def read_one_JSON(path): with open(path, 'rb', buffering=1024*1024) as f: raw_bytes = f.read() # 用支持字节串的JSON库解析(ujson/orjson/msgspec均可) data = ujson.loads(raw_bytes) return File(data)
2. 按磁盘物理顺序读取文件
- 操作方式:遍历文件前,通过
os.scandir()获取文件的inode(st_ino),按inode排序后再依次读取。 - 核心原理:文件的inode在磁盘上是连续分配的,按inode排序等价于按文件在磁盘上的物理存储位置排序,能大幅减少机械硬盘的磁头寻道时间(SSD也能降低随机IO的额外开销)。
- 示例代码:
import os json_dir = "/path/to/your/json/directory" # 按inode排序文件,确保物理顺序读取 sorted_entries = sorted(os.scandir(json_dir), key=lambda e: e.stat().st_ino) # 批量处理 file_instances = [read_one_JSON(entry.path) for entry in sorted_entries]
3. 减少路径解析与元数据查询开销
- 操作方式:提前获取目标目录的绝对路径,避免每次打开文件时重复解析相对路径;用
os.scandir()代替os.listdir(),因为前者返回的DirEntry对象已缓存文件元数据(如是否为文件、大小),无需额外调用os.stat()。 - 核心原理:13000次重复的路径解析和元数据查询会累积可观的系统调用开销,预缓存和提前处理能有效降低这部分耗时。
4. 禁用文件访问时间(atime)更新
- 操作方式:Linux/macOS系统可重新挂载文件系统时添加
noatime参数(如sudo mount -o remount,noatime /your/drive);Windows可通过注册表修改禁用NTFS的atime更新。 - 核心原理:默认情况下,系统每次读取文件都会更新文件的访问时间(atime),这会产生额外的磁盘写操作,禁用后能减少不必要的IO负载。
5. 简化文件操作流程
- 操作方式:确保
read_one_JSON函数中没有多余的文件指针操作(如f.seek()、f.tell()),一次性读取全部内容后立即关闭文件,避免不必要的IO交互。
内容的提问来源于stack exchange,提问作者Juraj
相关产品推荐
相关产品推荐

