Ref: 探寻C++最快的读取文件的方案

方法/平台/时间(秒) Linux gcc Windows mingw Windows VC2008
scanf 2.010 3.704 3.425
cin 6.380 64.003 19.208
cin取消同步 2.050 6.004 19.616
fread 0.290 0.241 0.304
read 0.290 0.398 不支持
mmap 0.250 不支持 不支持
Pascal read 2.160 4.668  

从上面可以看出几个问题

  1. Linux平台上运行程序普遍比Windows上快。
  2. Windows下VC编译的程序一般运行比MINGW(MINimal Gcc for Windows)快。
  3. VC对cin取消同步与否不敏感,前后效率相同。反过来MINGW则非常敏感,前后效率相差8倍。
  4. read本是linux系统函数,MINGW可能采用了某种模拟方式,read比fread更慢。
  5. Pascal程序运行速度实在令人不敢恭维。

不采用与采用read buffer的效果对比:(固态硬盘)

#if 1
g_bwtFile_idx = g_bwtFile_len;
do {
fread(&g_charbuf, , , g_bwtFile_fs_in);
g_Carr[(int)g_charbuf]++; } while((--g_bwtFile_idx) > );  // Time passed is: 2048 ms.
#else
do {
g_tmp_int = fread(&g_readBuf, , RBUF_SIZE, g_bwtFile_fs_in);
for(g_index_for = ; g_index_for < g_tmp_int; g_index_for++)
{
g_Carr[ (int)g_readBuf[g_index_for] ]++;
}
}while(g_tmp_int < g_readBuf);  // Time passed is: 79 ms.
#endif

Ref: Which is fastest: read, fread, ifstream or mmap?

method  millions of int. per s 
C read 70
C fread 124
C++ ifstream 124
mmap 125

简单的总结就是:
1. lseek 函数本身不会扩展文件的大小.
2. lseek 允许文件的偏移值超过文件的末端,如果下一次在这个偏移点写入数据,那么在偏移之前的文件末端与偏移点之间的数据将会自动填充为0。


计时方式: 同步与异步write的效率比较

    int ticks;
clock_t clockStart, clockEnd;
struct tms tmsStart, tmsEnd;
float userTime, sysTime, clockTime; printf("%-8s\t %-8s\t %-8s\t %-8s\t %-8s\t\n", "BUFFSIZE", "USER CPU", "SYSTEM CPU", "CLOCK CPU", "LOOP COUNT"); ticks = sysconf(_SC_CLK_TCK); for (;;) {
clockStart = times(&tmsStart); // ... clockEnd = times(&tmsEnd); userTime = (float)(tmsEnd.tms_utime - tmsStart.tms_utime)/ticks;
sysTime = (float)(tmsEnd.tms_stime - tmsStart.tms_stime)/ticks;
clockTime = (float)(clockEnd - clockStart)/ticks;
printf("%8d\t %8.2f\t %8.2f\t %8.2f\t %8d\n", buffSize, userTime, sysTime, clockTime, loopCount);
}

传参效率

对于内建的int char short long float等4字节或以下的数据类型而言

  实际上传递时也只需要传递1-4个字节,而使用指针传递时在32位cpu中传递的是32位的指针,4个字节,都是一条指令,这种情况下值传递和指针传递的效率是一样的,

  而传递double long long等8字节的数据时,

  •   在32位cpu中,其传值效率比传递指针要慢,因为8个字节需要2次取完。
  •   在64位的cpu上,传值和传址的效率是一样的。

  再说引用传递,这个要看编译器具体实现,

  引用传递最显然的实现方式是使用指针,这种情况下与指针的效率是一样的,

  而有些情况下编译器是可以优化的,采用直接寻址的方式,这种情况下,效率比传值调用和传址调用都要快,与上面说的采用全局变量方式传递的效率相当。

自定义的数据类型,class struct定义的数据类型。

  这些数据类型在进行传值调用时生成临时对象会执行构造函数,

  而且当临时对象销毁时会执行析构函数,如果构造函数和析构函数执行的任务比较多,或者传递的对象尺寸比较大,那么传值调用的消耗就比较大。

  这种情况下,采用传址调用和采用传引用调用的效率大多数下相当,正如上面所说,某些情况下引用传递可能被优化,总体效率稍高于传址调用。

执行效率

这里所说的执行效率,是指在被调用的函数体内执行时的效率。

  •   传值调用时,当值被传到函数体内,临时对象生成以后,所有的执行任务都是通过直接寻址的方式执行的,
  •   指针和大多数情况下的引用则是以间接寻址的方式执行的,所以实际的执行效率会比传值调用要低。

  如果函数体内对参数传过来的变量进行操作比较频繁,执行总次数又多的情况下,传址调用和大多数情况下的引用参数传递会造成比较明显的执行效率损失。

Thus,

综上所述,具体的执行效率要结合实际情况,通过比较传递过程的资源消耗执行函数体消耗之和来选择哪种情况比较合适。

而就引用传递和指针传递的效率上比,引用传递的效率始终不低于指针传递,所以从这种意义上讲,在c++中进行参数传递时优先使用引用传递而不是指针

如果没有必要,就使用值传递和引用传递,最好不用指针传递,更好地利用编译器的类型检查,使得我们有更少的出错机会,以增加代码的健壮性。

谨记:

  1. 内建的数据类型优先使用值传递,
  2. 自定义的数据类型,特别是传递较大的对象,请使用引用传递。

[Optimisation] Read & Write file on Hard Disk的更多相关文章

  1. Unix:关于一个file在file system和disk中占用空间

    參考文献: Harley Hahns:Guide to Unix and Linux. Chap 24 -->首先要有的关键概念:the amount of "disk space&q ...

  2. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  3. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  4. Java NIO read/write file through FileChannel

    referee:  Java NIO FileChannel A java nio FileChannel is an channel that is connected to a file. Usi ...

  5. 理解LGWR,Log File Sync Waits以及Commit的性能问题[转]

    理解LGWR,Log File Sync Waits以及Commit的性能问题 一.概要: 1.  Commit和log filesync的工作机制 2.  为什么log file wait太久 3. ...

  6. File I/O

    File I/O Introduction     We'll start our discussion of the UNIX System by describing the functions ...

  7. InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法

    InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法 140628  8:10:48 [Note] Plugi ...

  8. File System Design Case Studies

    SRC=http://www.cs.rutgers.edu/~pxk/416/notes/13-fs-studies.html Paul Krzyzanowski April 24, 2014 Int ...

  9. Extension of write anywhere file system layout

    A file system layout apportions an underlying physical volume into one or more virtual volumes (vvol ...

随机推荐

  1. json字符串转换对象的方法1

    为了方便读者了解json的使用,读者直接粘贴下面代码看效果即可: var json1 = {'name':'小李','age':'11','sex':'女'};console.log(json1.na ...

  2. data warehouse 1.0 vs 2.0

    data warehouse 1.01. EDW goal, separate data marts reqlity2. batch oriented etl3. IT driven BI - das ...

  3. react-native布局篇

    原文链接:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/react-native%E5%B8%83%E5%B1%80/ 一.宽度和 ...

  4. 用c#监控网络状态

    1.查询当前网络状态: using Microsoft.VisualBasic.Devices; //判断当前网络连接状态 Network nw=new Network(); if(nw.IsAvai ...

  5. java工具类,在Windows,Linux系统获取电脑的MAC地址、本地IP、电脑名

    package com.cloudssaas.util; import java.io.BufferedReader; import java.io.IOException; import java. ...

  6. [Beego模型] 五、构造查询

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

  7. 使用promise 和 generator来管理工作流

    根据p219的代码改编 示例代码如下 function oneStep(value){ return new Promise(function(resolve, reject){ resolve('o ...

  8. JVM的7种垃圾收集器:主要特点 应用场景 设置参数 基本运行原理

    原文地址:https://blog.csdn.net/tjiyu/article/details/53983650 下面先来了解HotSpot虚拟机中的7种垃圾收集器:Serial.ParNew.Pa ...

  9. [Aaronyang] 写给自己的WPF4.5 笔记13[二维自定义控件技巧-可视化状态实战,自定义容器,注册类命令,用户控件补充]

     我的文章一定要做到对读者负责,否则就是失败的文章  ---------   www.ayjs.net    aaronyang技术分享 博文摘要:欢迎大家来支持我的<2013-2015 Aar ...

  10. Github忽略keil工程生成的链接、编译等文件

    *.bak *.ddk *.edk *.lst *.lnp *.mpf *.mpj *.obj *.omf *.plg *.rpt *.tmp *.__i *.crf *.o *.d *.axf *. ...