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. Docker网络模式说明

    现在的Docker版本不推荐继续使用Link了,而是推荐用网络模式解决问题,简单讲一下最常用的几个网络模式,其他我用到时候再补充. bridge -net不加参数就是默认的bridge模式,这个默认b ...

  2. C++.Linux下redis编程:error while loading shared libraries: libhiredis.so.0.13

    编译 sudo gcc -o sltest01 sltest01.c -L/usr/local/lib/ -lhiredis 运行 sudo ./sltest01 编译成功后运行报错信息: ./slt ...

  3. perl 读写文件

    #http://perlmaven.com/open-and-read-from-files #mode operand create truncate#read < #write > y ...

  4. 【springboot】【socket】spring boot整合socket,实现服务器端两种消息推送

    参考地址:https://www.cnblogs.com/hhhshct/p/8849449.html

  5. Nodejs后台管理员登录实例

    思路: 直接访问后台页面时如果无session则跳转到404 当在登录页的表单提交时对数据库进行匹配,匹配成功生成session,否则提示用户名或密码错误 准备页面 :后台首页.登录页.404页, 步 ...

  6. [Android Pro] 关于Android 7.0无法进行https抓包的问题

    cp from  : https://www.cnblogs.com/wytings/p/6954293.html 在App进行数据请求的时候,如果每次都打印log去判断是一件很不“人性化”的操作行为 ...

  7. OAuth 2和JWT - 如何设计安全的API?

    OAuth 2和JWT - 如何设计安全的API? Moakap译,原文 OAuth 2 VS JSON Web Tokens: How to secure an API 本文会详细描述两种通用的保证 ...

  8. MUI中等待框的H5实现

    MUI没有内置的那个弹出转圈圈的那个等待框,那个nativeui.showwaiting是只能用于app中的,不能用在H5网页中的,网上找了下,找到个别人已经写好的,自己 测试了下没问题,先记下来 @ ...

  9. c#实现windows远程桌面连接程序代码

    使用winform制作windows远程桌面连接程序,windows自带了远程桌面连接,我们需要将远程桌面连接集成 到自己的winform程序,并实现管理远程主机的配置. 远程桌面核心类库 windo ...

  10. 基于mindwave脑电波进行疲劳检测算法的设计(1)

    一.简介 脑波,又称之为脑电波,是人大脑发出的电波,非常的微弱,只能通过设备来检测.人的脑波在不同状态下,会不同,因此可以通过脑波来量化分析人的精神状态. 科学家讲脑电波分为四种,以下为详细解释 (1 ...