zoukankan      html  css  js  c++  java
  • MATLAB中提高fwrite和fprintf函数的I/O性能

    提高fwritefprintf函数的I/O性能

    http://www.matlabsky.com/thread-34861-1-1.html

     

     

    今天我们将讨论下著名的fwrite(fprintf)函数,它们是用来进行二进制(文本)文件写入操作的。由于fwrite函数是底层I/O函数,且使用十分频繁,很多用户会质疑,它怎么可能还有性能提升的空间,要是有MathWorks早就更新了。

     

    Flushing Buffer

     

    不像C/C++语言,在MATLAB中调用fwirtefprintf)函数时,MATLAB会自动刷新(flush)输出缓存(buffer),这一点MATLAB的帮助文档没有正面直接了当的说明,只是在fopen函数中隐晦的涉及

    clip_image001

     

    看到这里,很多用户估计应该猜到了该怎么做了。在写入数据的时候,假如没有缓存(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);

    总的来说,本文中的技术同时适用于fprintffwrite函数,但是存储和读取二进制文件(fwrite/fread)远远快于文本文件(fprintf/fscanf/textscan),因此如果数据不是为了人为可读,尽量使用二进制保存!

     

    源文档 <http://blog.sina.com.cn/s/blog_61c0518f0101cckt.html>

  • 相关阅读:
    c语言实现BMP图像转换为灰度图
    360初赛溢出题
    vim的完全卸载
    小谈截断上传漏洞
    cmd提权的一些常用命令
    渗透测试方向概览
    字符编码以及python的编码解释
    BrainFuck 以及运用(idf)
    记一次加解密通关Nazo
    360 心情杂记
  • 原文地址:https://www.cnblogs.com/AI-Algorithms/p/3674463.html
Copyright © 2011-2022 走看看