[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 ...
随机推荐
- C# 8.0的新的using语法——Using declarations
我们在代码中经常使用using保障非托管资源的释放 static void Main(string[] args) { using (var options = Parse(args)) { if ( ...
- iOS 6 新的快捷初始化写法
转:http://www.2cto.com/kf/201408/328974.html 下列简化写法是IOS6.0以后的新写法 NSNumber //简化前的写法: NSNumber *value1; ...
- tomcat支持https的server.xml配置
访问地址:https://127.0.0.1/testWeb/mySevlet?url=123&action=aaa server.xml: <?xml version='1.0' en ...
- html5调用手机陀螺仪实现方向辨识
获取移动设备的陀螺仪,需要知道陀螺仪包含什么. 我们可以让document监听deviceorientation 来获取相关的数据,里面包括3个值 alpha.beta和gamma. 这三个值分别代表 ...
- WIN10平板 传递优化文件能否删除
在给系统准备做Ghost备份之前,一般会运行一次磁盘清理,但是WIN10系统多了一个传递优化文件(现在看到的体积很小,但其实可能是4-5G) 这个文件只是WIN10改进了系统更新策略产生的,就像是BT ...
- SSD卡对redis的影响
原文地址:http://antirez.com/news/52 Hello! As promised today I did some SSD testing. The setup: a Linux ...
- redis-desktop-manager 的简单使用
1:安装比较简单,所有软件几乎都一样(下载.安装)我就从安装好后,怎么玩记录吧!如下图,双击对应的图标就能打开此软件了 2-1:连接redis服务器的方式之一——导入对应的redis信息 连接配置的样 ...
- alter日志报WARNING: too many parse errors
数据库版本:12.2.0 操作系统版本:RHEL7.2 最近观察到一个数据库alert日志老是报硬解析太多错误,且对应的sql语句都是查看数据字典表: 2017-06-16T08:46:46.4174 ...
- ORA-214 signalled during: ALTER DATABASE MOUNT 问题
数据库服务器移动了位置,后来再连其数据库发现提示无法连接,大致为“无法为所有新实例创建连接...”,查看alert日志发现有如下错误: starting up 1 dispatcher(s) for ...
- 阿里云centos安装docker-engine实践
近日在阿里云ECS服务器(centos系统)中安装docker,参考官方指南 https://docs.docker.com/engine/installation/linux/centos/ 大概 ...