提高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性能的更多相关文章

  1. MFC中 CString类型用fprintf 函数写到文件中乱码的解决办法

    在上一篇中记录了用fprintf函数写内容到文件中的方法,但是发现了问题:产生的文件字符串有乱码现象. 解决办法:用_ftprintf函数 另外,据说: unicode的话要用fwprintf    ...

  2. matlab中求解线性方程组的rref函数

    摘自:http://www.maybe520.net/blog/987/ matlab中怎么求解线性方程组呢? matlab中求解线性方程组可应用克拉默法则(Cramer's Rule)即通过det( ...

  3. Matlab中常见的神经网络训练函数和学习函数

    一.训练函数 1.traingd Name:Gradient descent backpropagation (梯度下降反向传播算法 ) Description:triangd is a networ ...

  4. matlab中m文件与m函数的学习与理解

    1. m文件与m函数的区别 所谓 MATLAB 程序,大致分为两类: M 脚本文件 (M-Script) 和 M 函数 (M-function), 它们均是普通的 ASCII 码构成的文件. M 脚本 ...

  5. MATLAB中导入数据:importdata函数

    用load函数导入mat文件大家都会.可是今天我拿到一个数据,文件后缀名竟然是'.data'.该怎么读呢? 我仅仅好用matlab界面Workspace区域的"import data&quo ...

  6. 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]: 表示 ...

  7. matlab中的linkage和cluster函数

    Linkage: Agglomerative hierarchical cluster tree(凝聚成层次聚类树) 语法: 解释: Z=linkage(x),返回Z,是一个X矩阵中行的分层聚类树(用 ...

  8. Matlab中的cell、size函数

    参考网址:http://blog.sina.com.cn/s/blog_5efed5800100exmj.html Cell函数 如果p为一个数,那么h(1)=p,是没有问题的. 如果p为一个向量,那 ...

  9. matlab中fix, floor, ceil, round 函数的使用方法

    转载: https://www.ilovematlab.cn/thread-91895-1-1.html Matlab取整函数有: fix, floor, ceil, round.具体应用方法如下: ...

随机推荐

  1. IOS之--UI进阶--多控制器管理第一天

    01-项目中常见的文件(LaunchScreen) Xcode5 框架是苹果事先已经导入进去的.在项目的结构当中就能够看到导入的框架. Xcode6 会自动导入一些觉见的框架.在项目结构当中,看不到已 ...

  2. IOS之UI--自定义按钮实现代理监听点击事件

    前言: Objective-C提供的按钮监听事件的方法是 不含参数的监听方法 [button实例对象 addTarget:self action:@selector(func) forControlE ...

  3. 如何解决"应用程序无法启动,因为应用程序的并行配置不正确"问题

    应用程序事件日志中: "C:\windows\system32\test.exe"的激活上下文生成失败.找不到从属程序集 Microsoft.VC80.MFC,processorA ...

  4. Linux磁盘、目录、文件操作命令

    0x01. Linux磁盘分区与目录结构 ① 主分区.拓展分区.逻辑分区:早期主引导扇区MBR用64B存放主分区信息,每个分区用16B,因而上限为4个主分区,后来,因分区需求,引入拓展分区(类主分区) ...

  5. 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 条件

  6. oracle向in语句传入参数查不出数据

    在oracle字符串中使用了in,但是查不出数据 string getModel = "select * from TB_YBSH where ID in :ids"; Oracl ...

  7. 记一次linux服务器问题处理过程

    本周二的时候,涛哥找我,说明了一件事,在安装ganglia的时候,发生的一个问题. 在一台suse 10 sp1的服务器上,安装ganglia的一个依赖包,libconfuse.rpm,安装完成之后, ...

  8. LessonFifth Redis的持久化功能

    #验证redis的快照和AOF功能 1.先验证RDB快照功能,由于AOF优先级高,先关闭,然后测试,截图如下                 2.设置打开AOF 然后进行实验,截图如下:       ...

  9. Ubuntu 14.04 LTS Server 无法挂载光盘 启动initramfs等问题

    今天需要在戴尔R410服务器上装64位的Linux,师兄给了个14.04的server 64位镜像.一开始打算用U盘安装,用软碟通烧写镜像之后,在服务器端设置从U盘启动,但是安装到一半出现了光盘无法挂 ...

  10. 边工作边刷题:70天一遍leetcode: day 78

    Graph Valid Tree 要点:本身题不难,关键是这题涉及几道关联题目,要清楚之间的差别和关联才能解类似题:isTree就比isCycle多了检查连通性,所以这一系列题从结构上分以下三部分 g ...