[Optimisation] Read & Write file on Hard Disk
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 |
从上面可以看出几个问题
- Linux平台上运行程序普遍比Windows上快。
- Windows下VC编译的程序一般运行比MINGW(MINimal Gcc for Windows)快。
- VC对cin取消同步与否不敏感,前后效率相同。反过来MINGW则非常敏感,前后效率相差8倍。
- read本是linux系统函数,MINGW可能采用了某种模拟方式,read比fread更慢。
- 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++中进行参数传递时优先使用引用传递而不是指针。
如果没有必要,就使用值传递和引用传递,最好不用指针传递,更好地利用编译器的类型检查,使得我们有更少的出错机会,以增加代码的健壮性。
谨记:
- 内建的数据类型优先使用值传递,
- 自定义的数据类型,特别是传递较大的对象,请使用引用传递。
[Optimisation] Read & Write file on Hard Disk的更多相关文章
- Unix:关于一个file在file system和disk中占用空间
參考文献: Harley Hahns:Guide to Unix and Linux. Chap 24 -->首先要有的关键概念:the amount of "disk space&q ...
- [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 ...
- 本人SW知识体系导航 - Programming menu
将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...
- 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 ...
- 理解LGWR,Log File Sync Waits以及Commit的性能问题[转]
理解LGWR,Log File Sync Waits以及Commit的性能问题 一.概要: 1. Commit和log filesync的工作机制 2. 为什么log file wait太久 3. ...
- File I/O
File I/O Introduction We'll start our discussion of the UNIX System by describing the functions ...
- 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 ...
- File System Design Case Studies
SRC=http://www.cs.rutgers.edu/~pxk/416/notes/13-fs-studies.html Paul Krzyzanowski April 24, 2014 Int ...
- Extension of write anywhere file system layout
A file system layout apportions an underlying physical volume into one or more virtual volumes (vvol ...
随机推荐
- zookeeper leader选举机制
最近看了下zookeeper的源码,先整理下leader选举机制 先看几个关键数据结构和函数 服务可能处于的状态,从名字应该很好理解 public enum ServerState { LOOKING ...
- javascript 原生常用api 数组方法大全
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 还在为工作发愁?学JavaScript吧
事实上,每家专业招聘机构,从Glassdoor.com和Linkedin到美国劳工部,都报导了就业市场对开发人员需求的增长速度出于意料地快.这种需求可能已经不新鲜了,但是就业市场对哪种开发语言的需求量 ...
- 端口转发工具rinetd的安装与配置
端口映射和转发在实际应用中非常常见,比如一个局域网只有一台服务器可以被互联网访问到,那么如果想通过互联网访问局域网中其他的服务,最常用的方式就是在这一台机器上开放端口,然后转发至局域网中其他主机的端口 ...
- Visio画流程图风格设置
第一步:选取设计下选用“简单” 第二步:设置颜色为“铅笔” 第三步:设置效果为“辐射” 第四步:效果
- [Algorithm] Calculate Pow(x,n) using recursion
Asking you to implement the Math.pow method The navie implemenation can be: // O(N) const pow1 = (x, ...
- Java字节码 小结
Reference javap 基本使用方法 深入理解java字节码 从Java代码到字节码 Java字节码.class文件案例分析 字节码 核心概念 Class文件是8位字节流,按字节对齐.之所以称 ...
- Redis集群搭建(转自一菲聪天的“Windows下搭建Redis集群”)
配置Redis参考:http://blog.csdn.net/zsg88/article/details/73715947 使用Ruby配置集群参考:https://www.cnblogs.com/t ...
- Warning: Function created with compilation errors.
SQL> create or replace function 2 remove_constants(p_query in varchar2) return varchar2 3 as 4 l_ ...
- tensorflow 笔记7:tf.concat 和 ops中的array_ops.concat
用于连接两个矩阵: mn = array_ops.concat([a, d], 1) # 按照第二维度相接,shape1 [m,a] shape2 [m,b] ,concat_done shape ...