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.具体应用方法如下: ...
随机推荐
- 安装concrete时提示“...database does not support InnoDB database tables..."如何解决
安装很多系统时,经常有有提示: "...database does not support InnoDB database tables..." 解决办法: 找到MySQL的配置文 ...
- python 连接 mysql
http://blog.csdn.net/yelbosh/article/details/7498641 数据库的连接 模块引入之后我们就需要和数据库进行连接了,实例代码如下: db = MySQLd ...
- apache 开启zgip 压缩模式
一.Apache开启gzip压缩模式在目录apache\conf\httpd.conf 配置 httpd.conf 文件: #去掉LoadModule deflate_module modules/m ...
- Python基本数据结构-集合-创建/与其他类型比较
- Python基本数据结构-字典-创建/访问/基本操作/格式化输出
- PE文件结构部分解析以及输入的定位
原文链接地址:http://www.cnblogs.com/shadow-lei/p/3554670.html PE文件定义 PE 文件("Portable executable" ...
- Nginx为什么比Apache Httpd高效:原理篇
一.进程.线程? 进程是具有一定独立功能的,在计算机中已经运行的程序的实体.在早期系统中(如linux 2.4以前),进程是基本运作单位,在支持线程的系统中(如windows,linux2.6)中,线 ...
- SSH 端口映射(一)
转载:http://blog.csdn.net/a351945755/article/details/21785647,http://blog.csdn.net/gaoming655/article/ ...
- Keepalived高可用集群搭建(转载linuxIDC)
1.Keepalived简介 Keepalived是一个基于VRRP协议来实现的WEB服务高可用方案,可以利用其来避免单点故障.使用多台节点安装keepalived.其 他的节点用来提供真实的服务,同 ...
- 内存流和null字节
#include <stdio.h> #include <string.h> int main() { ]={}; FILE* fp = fmemopen(buf,," ...