提高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--小实例项目--添加商品和商品名(纯代码终结版)

    前言:这个小实例项目是完完全全以MJ视频传授的优化方案一步一个思路从零开始敲出代码的,而且每一步都有思路,都有逻辑所以然.敲代码讲究思路,我个人不建议记忆太多东西,反正我记性很差的. 小贴士:文章末尾 ...

  2. char与TCHAR相互转化

    char与TCHAR相互转化 char strUsr[10] = "Hello"; TCHAR Name[100]; #ifdef UNICODE MultiByteToWideC ...

  3. Http协议中 常用的参数应用

    1 请求来自哪一个页面 request.getHeader("referer"); 在购买页,通过a标签进入AddressAction中,地址保存后,需要跳到原先的页面. 另外,另 ...

  4. ERROR: The partition with /var/lib/mysql is too full! failed!

    发现:ERROR: The partition with /var/lib/mysql is too full! failed! 然后df -h 发现硬盘100%   于是分析到底什么占用了这近两百G ...

  5. 设计模式C#实现(六)——单例模式

    单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 构成: 1.私有的构造函数 2.私有静态的实例 3.返回实例的静态方法 public class Singleton { privat ...

  6. 【VB超简单入门】二、知识准备

    在开始编程之前,需要先熟悉一下各种操作和术语,以后学习编程才能得心应手. 首先最重要的操作当然就是-电脑的开机关机啦~(开个玩笑哈哈),必须掌握软件的安装和卸载,还有能编写批处理程序对平时的使用也是很 ...

  7. UVA 10827 Maximum sum on a torus (LA)

    算法入门经典训练指南88页练习 ::这道题只要把原矩阵扩大4倍,那么其跟最大子矩阵的题目就很类似,把二维转化成一维,求最大的序列和,不过这个序列的长度不能超过n. 长度不能超过n? 那这道题又跟hdu ...

  8. 22 扩展Python - 《Python 核心编程》

  9. shell exit 0 exit 1

    其实都一样,都是退出,只不过返回这个0和1是返回给操作系统的错误或者正确代码. exit 1 指的是脚本运行的返回值,用来指示成功或失败,以及失败的原因. exit 0 表示成功,exit 1表示失败 ...

  10. Centos7 搭建hadoop2.6 HA

    用户配置: User :root Password:toor 2.创建新用户 student Pwd: student 3.安装virtualbox的增强工具软件 4.系统默认安装的是openjdk ...