MATLAB中提高fwrite和fprintf函数的I/O性能
提高fwrite和fprintf函数的I/O性能
http://www.matlabsky.com/thread-34861-1-1.html
今天我们将讨论下著名的fwrite(fprintf)函数,它们是用来进行二进制(文本)文件写入操作的。由于fwrite函数是底层I/O函数,且使用十分频繁,很多用户会质疑,它怎么可能还有性能提升的空间,要是有MathWorks早就更新了。
Flushing 和 Buffer
不像C/C++语言,在MATLAB中调用fwirte(fprintf)函数时,MATLAB会自动刷新(flush)输出缓存(buffer),这一点MATLAB的帮助文档没有正面直接了当的说明,只是在fopen函数中隐晦的涉及
看到这里,很多用户估计应该猜到了该怎么做了。在写入数据的时候,假如没有缓存(buffer),那么每次调用fwrite函数,就需要进行一次文件写入操作,这种方式将严重降低I/O性能!
下面看一组比较数据,首先我们没有使用缓存方式
data = randi(250,1e6,1); % 生成一组数据,用来测试I/O性能
% 标准形式,没有应用缓存输出 - 慢
fid = fopen('demo.dat', 'wb'); % w是小写,b表示二进制
tic, for idx = 1:length(data), fwrite(fid,data(idx)); end, toc
fclose(fid);
Elapsed time is 14.983201 seconds.
消耗了大概15s,下面看看使用缓存的方式
% 缓存输出模式 – 快3倍
fid = fopen('demo.dat', 'Wb'); % 注意W是大写,b表示二进制
tic, for idx = 1:length(data), fwrite(fid,data(idx)); end, toc
fclose(fid);
Elapsed time is 5.616357 seconds.
使用缓存后时间缩短至5.6s,看来效率提高了不少呀!
我们无法理解MathWorks为什么将fopen默认设置为非缓存模式,但也许有他们的理由吧!不过当您在写大型数据文件的时候,推荐还是使用缓存模式('w')吧!
Chunking I/O
使用缓存进行写操作,其实就是为了减少数据文件的访问次数,因此在MATLAB中,假如先将所有的数据都准备好,然后一次性调用fwrite函数将其写入文件中
fid = fopen('demo.dat', 'wb'); % 注意是小写w
tic, fwrite(fid,data); toc
fclose(fid);
Elapsed time is 0.034816 seconds.
可以看出即使是非缓存模式,写入30ms的效率还是很高的。
但是假如我们读写的是网络文件,由于网络原因可能需要较长的时间,此时将大数据拆开成很多小块,然后分块处理是一个明智的选择。
h = waitbar(0, 'Saving data...', 'Name','Saving data...');
cN = 100; % number of steps/chunks
% Divide the data into chunks (last chunk is smaller than the rest)
dN = length(data);
dataIdx = [1 : round(dN/cN) : dN, dN+1]; % cN+1 chunk location indexes
% Save the data
fid = fopen('test.dat', 'Wb');
for chunkIdx = 0 : cN-1
% Update the progress bar
fraction = chunkIdx/cN;
msg = sprintf('Saving data... (%d%% done)', round(100*fraction));
waitbar(fraction, h, msg);
% Save the next data chunk
chunkData = data(dataIdx(chunkIdx+1) : dataIdx(chunkIdx+2)-1);
fwrite(fid,chunkData);
end
fclose(fid);
close(h);
总的来说,本文中的技术同时适用于fprintf和fwrite函数,但是存储和读取二进制文件(fwrite/fread)远远快于文本文件(fprintf/fscanf/textscan),因此如果数据不是为了人为可读,尽量使用二进制保存!
源文档 <http://blog.sina.com.cn/s/blog_61c0518f0101cckt.html>
MATLAB中提高fwrite和fprintf函数的I/O性能的更多相关文章
- MFC中 CString类型用fprintf 函数写到文件中乱码的解决办法
在上一篇中记录了用fprintf函数写内容到文件中的方法,但是发现了问题:产生的文件字符串有乱码现象. 解决办法:用_ftprintf函数 另外,据说: unicode的话要用fwprintf ...
- matlab中求解线性方程组的rref函数
摘自:http://www.maybe520.net/blog/987/ matlab中怎么求解线性方程组呢? matlab中求解线性方程组可应用克拉默法则(Cramer's Rule)即通过det( ...
- Matlab中常见的神经网络训练函数和学习函数
一.训练函数 1.traingd Name:Gradient descent backpropagation (梯度下降反向传播算法 ) Description:triangd is a networ ...
- matlab中m文件与m函数的学习与理解
1. m文件与m函数的区别 所谓 MATLAB 程序,大致分为两类: M 脚本文件 (M-Script) 和 M 函数 (M-function), 它们均是普通的 ASCII 码构成的文件. M 脚本 ...
- MATLAB中导入数据:importdata函数
用load函数导入mat文件大家都会.可是今天我拿到一个数据,文件后缀名竟然是'.data'.该怎么读呢? 我仅仅好用matlab界面Workspace区域的"import data&quo ...
- matlab中的size(),length(),ndims()函数的使用方法
1.size()使用方法: size(a)表示矩阵每一个维度的长度 比方size([1 2 3;4 5 6]) 等于[2 3]: 表示他有2行3列. size([1 2 3]) 等于[1 3]: 表示 ...
- matlab中的linkage和cluster函数
Linkage: Agglomerative hierarchical cluster tree(凝聚成层次聚类树) 语法: 解释: Z=linkage(x),返回Z,是一个X矩阵中行的分层聚类树(用 ...
- Matlab中的cell、size函数
参考网址:http://blog.sina.com.cn/s/blog_5efed5800100exmj.html Cell函数 如果p为一个数,那么h(1)=p,是没有问题的. 如果p为一个向量,那 ...
- matlab中fix, floor, ceil, round 函数的使用方法
转载: https://www.ilovematlab.cn/thread-91895-1-1.html Matlab取整函数有: fix, floor, ceil, round.具体应用方法如下: ...
随机推荐
- IOS之--UI进阶--多控制器管理第一天
01-项目中常见的文件(LaunchScreen) Xcode5 框架是苹果事先已经导入进去的.在项目的结构当中就能够看到导入的框架. Xcode6 会自动导入一些觉见的框架.在项目结构当中,看不到已 ...
- IOS之UI--自定义按钮实现代理监听点击事件
前言: Objective-C提供的按钮监听事件的方法是 不含参数的监听方法 [button实例对象 addTarget:self action:@selector(func) forControlE ...
- 如何解决"应用程序无法启动,因为应用程序的并行配置不正确"问题
应用程序事件日志中: "C:\windows\system32\test.exe"的激活上下文生成失败.找不到从属程序集 Microsoft.VC80.MFC,processorA ...
- Linux磁盘、目录、文件操作命令
0x01. Linux磁盘分区与目录结构 ① 主分区.拓展分区.逻辑分区:早期主引导扇区MBR用64B存放主分区信息,每个分区用16B,因而上限为4个主分区,后来,因分区需求,引入拓展分区(类主分区) ...
- mysql连接其他表删除某个表的数据
delete a from TableA a left join TableB b on a.XX = b.YY left join TableC c on c.ZZ = a.XX where 条件
- oracle向in语句传入参数查不出数据
在oracle字符串中使用了in,但是查不出数据 string getModel = "select * from TB_YBSH where ID in :ids"; Oracl ...
- 记一次linux服务器问题处理过程
本周二的时候,涛哥找我,说明了一件事,在安装ganglia的时候,发生的一个问题. 在一台suse 10 sp1的服务器上,安装ganglia的一个依赖包,libconfuse.rpm,安装完成之后, ...
- LessonFifth Redis的持久化功能
#验证redis的快照和AOF功能 1.先验证RDB快照功能,由于AOF优先级高,先关闭,然后测试,截图如下 2.设置打开AOF 然后进行实验,截图如下: ...
- Ubuntu 14.04 LTS Server 无法挂载光盘 启动initramfs等问题
今天需要在戴尔R410服务器上装64位的Linux,师兄给了个14.04的server 64位镜像.一开始打算用U盘安装,用软碟通烧写镜像之后,在服务器端设置从U盘启动,但是安装到一半出现了光盘无法挂 ...
- 边工作边刷题:70天一遍leetcode: day 78
Graph Valid Tree 要点:本身题不难,关键是这题涉及几道关联题目,要清楚之间的差别和关联才能解类似题:isTree就比isCycle多了检查连通性,所以这一系列题从结构上分以下三部分 g ...