内存映射模块读写文件提高IO性能mmap
内存映射模块读写文件提高IO性能mmap
1.概述
这篇文章介绍下与普通读写文件不同的方式,内存映射读写文件。在什么情况下才会用到内存映射操作文件那,还是要先了解下他。
1.1.内存映射与IO区别
常规操作IO开销
常规的操作文件是经过下面几个环节操作IO读写文件,操作过程比较复杂耗费时间较长。尤其是操作大文件时需要不断的增加IO操作次数,延迟就会增大。
- 通过系统调用将控制权转移到内核或核心操作系统代码
- 与文件所在的物理磁盘交互
- 将数据复制到用户空间和内核空间之间的不同缓冲区
内存映射开销
避免此开销的一种方法是使用内存映射文件。您可以将内存映射描绘成一个过程,在该过程中,读取和写入操作跳过上述许多层并将请求的数据直接映射到物理内存中。因为对于每次访问它不涉及单独的系统调用,也不会在缓冲池之间复制数据,而是内核和用户程序可以直接访问内存。
内存映射文件 I/O 方法为了速度而牺牲了内存使用量,这通常称为时空权衡。但是,内存映射不必使用比传统方法更多的内存。操作系统非常聪明。它将在请求时延迟加载数据,类似于 Python 生成器的工作方式。
此外,借助虚拟内存,您可以加载大于物理内存的文件。但是,当没有足够的物理内存用于文件时,您不会看到内存映射带来的巨大性能改进,因为操作系统将使用较慢的物理存储介质(如固态磁盘)来模拟它缺少的物理内存。
2.测试数据
所有的例子都将使用文本文件 lorem.txt,在当前目录创建lorem.txt文件,并复制下面的内容到文件。
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec egestas, enim et consectetuer ullamcorper, lectus ligula rutrum leo,
a elementum elit tortor eu quam. Duis tincidunt nisi ut ante. Nulla
facilisi. Sed tristique eros eu libero. Pellentesque vel
arcu. Vivamus purus orci, iaculis ac, suscipit sit amet, pulvinar eu,
lacus. Praesent placerat tortor sed nisl. Nunc blandit diam egestas
dui. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Aliquam viverra fringilla
leo. Nulla feugiat augue eleifend nulla. Vivamus mauris. Vivamus sed
mauris in nibh placerat egestas. Suspendisse potenti. Mauris
massa. Ut eget velit auctor tortor blandit sollicitudin. Suspendisse
imperdiet justo.
3.内存映射操作文件
3.1.读取内容
使用 mmap() 创建一个内存映射文件对象,mmap是一个类,它的构造器参数如下
- fileno:是一个文件描述符,要么是来自 file 对象的 fileno() 方法, 要么来自 os.open()。使用者负责在调用 mmap() 之前打开文件,并且在使用结束之后关闭它。
- length:入 mmap() 的参数是要去映射的文件内容的大小。如果值是 0 ,那么代表映射整个文件。如果这个值超过当前文件,文件将会被扩展
- tagname=Non
- access=None:ACCESS_READ 表示只读,ACCESS_WRITE 表示直接写(对内存的操作直接写入文件),或者 ACCESS_COPY 用于写时复制(内存分配不写入文件)
- offset=None
import mmapwith open('lorem.txt', 'r') as f:with mmap.mmap(f.fileno(), 0,access=mmap.ACCESS_READ) as m:print('First 10 bytes via read :', m.read(10))print('First 10 bytes via slice:', m[:10])print('2nd 10 bytes via read :', m.read(10))
文件指针会追踪切片操作上次读取的位置。这个例子中,第一次读取之后指针向前移动了 10 字节。在切片操作开始之前,文件指针重置到文件开始处,然后又向前移动了 10 字节。切片操作之后,调用 read(10) 将会得到文件 11-20 字节的内容。
First 10 bytes via read : b'Lorem ipsu'
First 10 bytes via slice: b'Lorem ipsu'
2nd 10 bytes via read : b'm dolor si'
3.2.写
为了设置一个内存映射文件去接受更新,要以追加模式 r+ (而不是 w)打开然后再进行映射。然后可以使用任何更新数据的 API有两种方式改变内容,调用write方法和切片方式修改。
1.切片方式修改内容
import mmap
import shutil# 复制示例文件
shutil.copyfile('lorem.txt', 'lorem_copy.txt')word = b'consectetuer'
reversed = word[::-1]
print('Looking for :', word)
print('Replacing with :', reversed)with open('lorem_copy.txt', 'r+') as f:with mmap.mmap(f.fileno(), 0) as m:print('Before:\n{}'.format(m.readline().rstrip()))m.seek(0) # rewindloc = m.find(word)# 通过切片方式修改文件内容m[loc:loc + len(word)] = reversedm.flush()m.seek(0) # rewindprint('After :\n{}'.format(m.readline().rstrip()))f.seek(0) # rewindprint('File :\n{}'.format(f.readline().rstrip()))
运行结果,内存和文件中第一行中间部分的 「consectetuer」将被替换。
Looking for : b'consectetuer'
Replacing with : b'reutetcesnoc'
Before:
b'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'
After :
b'Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.'
File :
Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.
2.write方法修改内容
import mmapdef mmap_io_write(filename, text):with open(filename, mode="w", encoding="utf-8") as file_obj:with mmap.mmap(file_obj.fileno(), length=0, access=mmap.ACCESS_WRITE) as mmap_obj:mmap_obj.write(text)
3.3.复制
使用模式 ACCESS_COPY 访问文件,将不会将更新内容写入到磁盘文件
import mmap
import shutil# 复制示例文件
shutil.copyfile('lorem.txt', 'lorem_copy.txt')word = b'consectetuer'
reversed = word[::-1]with open('lorem_copy.txt', 'r+') as f:with mmap.mmap(f.fileno(), 0,# 复制模式access=mmap.ACCESS_COPY) as m:print('Memory Before:\n{}'.format(m.readline().rstrip()))print('File Before :\n{}\n'.format(f.readline().rstrip()))m.seek(0) # rewindloc = m.find(word)# 修改文件内容m[loc:loc + len(word)] = reversedm.seek(0) # rewindprint('Memory After :\n{}'.format(m.readline().rstrip()))f.seek(0)print('File After :\n{}'.format(f.readline().rstrip()))
这个例子中将文件句柄和 mmap 句柄分开是必要的,with句柄是f,mmap句柄是m,因为两个对象的内部状态是单独维护的。
运行结果中access=mmap.ACCESS_COPY)复制模式只修改了内存中的文件内容,不会将内容写入到磁盘。
Looking for : b'consectetuer'
Replacing with : b'reutetcesnoc'
Before:
b'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'
After :
b'Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.'
File :
Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.
3.4.正则表达式
因为一个内存映射文件拥有一个字符串的行为,因此可以使用其他操作字符串的模块(如正则表达式)一起使用。这个例子中将会找到所有以「nulla」开始的句子
import mmap
import repattern = re.compile(rb'(\.\W+)?([^.]?nulla[^.]*?\.)',re.DOTALL | re.IGNORECASE | re.MULTILINE)with open('lorem.txt', 'r') as f:with mmap.mmap(f.fileno(), 0,access=mmap.ACCESS_READ) as m:for match in pattern.findall(m):print(match[1].replace(b'\n', b' '))
运行结果
b'Nulla facilisi.'
b'Nulla feugiat augue eleifend nulla.'
相关文章:
内存映射模块读写文件提高IO性能mmap
内存映射模块读写文件提高IO性能mmap 1.概述 这篇文章介绍下与普通读写文件不同的方式,内存映射读写文件。在什么情况下才会用到内存映射操作文件那,还是要先了解下他。 1.1.内存映射与IO区别 常规操作IO开销 常规的操作文件是经过下面几个环节操作I…...
存储硬件与协议
存储硬件与协议存储设备的历史轨迹存储介质的进化3D NAND3D XPointIntel Optane存储接口协议的演变NVMeNVMe-oF网络存储技术1)DAS2)NAS3)SAN4)iSCSIiSCSI层次结构存储设备的历史轨迹 1.穿孔卡2.磁带3.硬盘4.磁盘(软盘…...
智能物流半导体发展
智能物流半导体在国内的发展,国内巨大的人口基数,这将会不断促进智慧物流的发展。智能物流在未来发展的潜力巨大。 关于触屏的设计是界面越简单,越清晰越好,最近设计一个小车控制触屏软件。把小车当前所在信息通过图像显示出来。…...
SAP S/4HANA 概述
智能企业业务技术平台Business Technology Platform提供数据管理和分析,并支持应用程序开发和集成。它还允许我们的客户使用人工智能、机器学习和物联网等智能技术来推动创新。业务网络Business network帮助客户实现跨公司业务流程的数字化。该网络建立在我们的采购…...
太上感应篇
太上感应篇原文 太上曰。祸福无门。惟人自召。善恶之报。如影随形。 是以天地有司过之神。依人所犯轻重。以夺人算。算减则贫耗。多逢忧患。人皆恶之。刑祸随之。吉庆避之。恶星灾之。算尽则死。 又有三台北斗神君。在人头上。录人罪恶。夺其纪算。又有三尸神。在人身中。每…...
FPGA入门系列17--task
文章简介 本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码…...
React学习笔记(番外二)——列表多选批量处理复合组件
React学习笔记(番外二)——列表多选批量操作复合组件前言〇、Show you the code一、 任务分析及拆解表头行的Checkbox——总开关记录行的Checkbox——行级开关二、 基础实现表头行的文件——header-row.js记录行的文件——record-row.js页面的文件App.js…...
Pom.xml详解
目录 1、Maven的下载安装 2、什么是pom? 3、较完整的pom元素 4、默认生成Maven工程的pom内容 5、自定义的属性变量 6、依赖管理 6.1、整体依赖关系列表 6.2、依赖关系的传递性 6.3、依赖传递可能造成的问题 6.3.1、scope依赖范围 6.3.2、依赖调节 6.3.3…...
浅谈软件测试需求管理
什么是需求管理? 需求管理,指对产品、系统或工程的开发需求的搜集、定义、分析、评审、整理、维护、追溯和复用等相关的管理工作和流程。通常特指应用程序或软件系统的研发需求。需求管理和配置管理、测试管理、缺陷管理、风险管理、变更管理等管理流程…...
面试题复盘
Vuex与本地存储的区别Vuex是一个专门为Vue.js应用程序开发的状态管理模式和库。它提供了一个中央存储库,用于存储应用程序的所有组件之间共享的状态【组件间通信的一种方法,一般用于中大型应用】。Vuex的主要目的是在Vue.js应用程序中管理复杂的状态逻辑…...
Telerik UI for WPF 2023 R1
Telerik UI for WPF 2023 R1 之 WPF 的 Telerik 用户界面,WPF 控件库开发人员信任,快速构建美观、高性能的 WPF 业务应用程序。现在支持 .NET 6 和 7.0。 概述部分背景图像 主要特征 现代专业主题图标,现代专业主题 通过各种受 Office、Wind…...
基于 CentOS7 的 KVM 部署 + 虚拟机创建
目录一、实验环境二、部署 KVM三、创建虚拟机四、远程管理 KVM 虚拟机FAQ一、实验环境 实验环境:VMware Workstation 16 Pro 打开虚拟机之前,首先开启 VMware Workstation Pro 16 上的硬件辅助虚拟化功能,如下图所示: 二、部署 …...
Python自动化测试实战篇(5)优化selenium+unittest+ddt,搞定100条测试用例只执行前50条
这些是之前的文章,里面有一些基础的知识点在前面由于前面已经有写过,所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇(1)读取xlsx中账户密码,unittest框架实现通过requests接口post登录网站请求&…...
C语言--数据的存储2
目录前言练习有符号类型与无符号类型char类型的取值范围有符号char无符号char有符号与无符号类型混合运算有符号无符号类型形成的bugchar类型取值范围应用浮点型在内存中的存储浮点数的存储浮点数存储规则浮点数取出规则前言 上篇文章我们讲解了数据类型,类型的基本…...
Ubuntu 安装 Qt5.7.0
下载 地址:https://download.qt.io/https://download.qt.io/ 文件夹说明: snapshots:预览版,该文件夹中包含最新的测试版本。 online:在线安装包。 official_releases:最终发布版。 new_archive&#…...
“世界”的伊利,“三难”的潘刚
(图片来源于网络,侵删) 来源 | 螳螂观察 文 | 叶小安 一棵草,一头牛,到一杯牛奶,乳品如何守住舌尖上的安全? 央视财经频道专访中,伊利集团董事长兼总裁潘自信满满地介绍了现代智…...
【新】华为OD机试 - 开心消消乐(Python)
开心消消乐 题目 给定一个 N 行 M 列的二维矩阵,矩阵中每个位置的数字取值为 0 或 1,矩阵示例如: 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1现需要将矩阵中所有的 1 进行反转为 0,规则如下: 当点击一个 1 时,该 1 被反转为 0,同时相邻的上、下、左、右,以及左上、左下、右上…...
山东大学2022-2023数据仓库挖掘期末考题回忆
2023.2.14 一、 1.数据预处理的过程和解决问题 2.什么是离群点,检测离群点的四个方法 3.数据仓库的四个特点,画出数据仓库结构图 4.维度归约的两个方法及区别。 二、 两个模型用来预测新冠病毒的阳性和阴性 1.分别求准确率,精确率,…...
SSM整合
SSM整合 ContextLoaderListener Spring提供了监听器ContextLoaderListener,实现ServletContextListener接口,可监听 ServletContext的状态,在web服务器的启动,读取Spring的配置文件,创建Spring的IOC容器。 web 应用中…...
Android平台版本所对应的 API 级别
平台版本API级别版本号备注Android 1333TIRAMISU平台亮点Android 1232S_V2平台亮点31S平台亮点Android 1130R平台亮点Android 1029Q平台亮点Android 928P平台亮点Android 8.127O_MR1平台亮点Android 8.026O平台亮点Android 7.1.1Android 7.125N_MR1平台亮点Android 7.024N平台亮…...
GIS小白必看!Global Mapper处理正射影像的5个高频问题解答(含奥维地图导入避坑指南)
GIS新手实战指南:Global Mapper正射影像处理全解析 第一次打开Global Mapper时,那些密密麻麻的工具栏和复杂的参数设置确实让人望而生畏。去年我刚接触GIS时,处理无人机航拍的正射影像就踩了不少坑——坐标系选错导致影像偏移几百米、导出分幅…...
基于comsol的三相电力变压器电磁场与电路耦合计算的电压电流及磁通密度分布分析
comsol三相电力变压器电磁场和电路耦合计算,可以得到变压器高低压绕组电压电流分布以及变压器磁通密度分布三相电力变压器建模这事儿,说难不难说简单也不简单。前两天用COMSOL折腾了个带电路耦合的模型,顺手把绕组电流分布和铁芯磁通都摸清楚…...
[2026 职场洗牌系列 01] 程序员正在“杀死”自己的工作?科技行业高危预警
长久以来,学计算机(CS)在很多年轻人眼里就等同于拿到了通往高薪和阶层跃升的金钥匙。大家都觉得,只要把代码敲得溜,这辈子在职场上基本就稳了。可惜,到了2026年的今天,生成式AI正在毫不留情地把…...
rBase64:嵌入式系统零堆分配BASE64编解码库
1. rBase64 库深度解析:面向嵌入式系统的高性能 BASE64 编解码实现BASE64 是一种将任意二进制数据映射为 ASCII 字符子集的编码方案,广泛应用于嵌入式通信协议(如 MQTT payload、HTTP Basic Auth、CoAP 传输)、固件 OTA 升级包签名…...
【专栏二:深度学习】-【一张图讲清楚:什么是向前传输和向后传输】
文章目录前言一、输入数据:训练从样本开始二、向前传播:模型先算出一个预测结果三、先把第一个公式讲明白:为什么会有 z Wx b?四、只有线性计算还不够,所以还需要激活函数1. ReLU2. Sigmoid五、预测结果:…...
MAC动态库加载路径优化:从@rpath到install_name_tool实战解析
1. 动态库加载路径问题的本质 当你第一次在Mac上遇到"Library not loaded"错误时,那种感觉就像在陌生城市迷了路。我清楚地记得自己早期开发时,控制台突然抛出红色错误信息的场景: dyld: Library not loaded: libAwesome.dylibRefe…...
像素幻梦·创意工坊应用场景:复古风APP启动页加载动画AI生成方案
像素幻梦创意工坊应用场景:复古风APP启动页&加载动画AI生成方案 1. 引言:像素艺术的复兴与AI赋能 在移动应用设计领域,复古像素风格正经历一场文艺复兴。从独立游戏到主流应用,越来越多的产品选择用像素艺术打造独特的品牌识…...
Docker+iredmail搭建企业级邮件服务器全流程(附常见问题排查)
Dockeriredmail搭建企业级邮件服务器全流程指南 邮件系统作为企业日常沟通的核心基础设施,其稳定性和安全性直接影响业务运转效率。传统邮件服务器部署往往需要复杂的配置和漫长的调试周期,而Docker容器化技术结合iredmail开源邮件解决方案,为…...
保姆级教程:用 Modelfile 快速部署 ModelScope 的 GGUF 模型到 Ollama(以 DeepSeek 为例)
从零到一:用Modelfile高效部署ModelScope的GGUF模型至Ollama实战指南 在本地运行大语言模型正成为开发者探索AI边界的新常态。不同于直接调用云端API,本地部署能带来数据隐私保障、响应速度提升以及模型深度定制等独特优势。Ollama作为轻量级模型运行框架…...
3D打印机步进电机参数计算全攻略:从同步带到丝杆的实战配置
3D打印机步进电机参数计算全攻略:从同步带到丝杆的实战配置 在DIY 3D打印机的过程中,步进电机的参数计算往往是让初学者最头疼的环节之一。无论是同步带驱动的XY轴,还是丝杆控制的Z轴,亦或是齿轮传动的挤出机构,都需要…...
