C/C++如何加速输入输出效率(上)

点击打开在线编译器,边学边练

1. 简介

遇到大数据时,往往读写文件成了程序运行速度的瓶颈,需要更快的读取方式。相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,有很多案例中提供几个数据,却在后台测评却提供了近千,近万的数据量是常事,而很多人会发现,明明算法正确的问题,却总是在超时,但把自己的输入换成scanf,输出换成printf之后莫名其妙又可以通过了,于是便冷眼相对C++的cin与cout。

在C++中,cin与cout往往不需要我们手动设置格式而变得灵活,因此更趋向于我们便捷式的使用,但这并不是说cin与cout就一定比scanf和printf慢,我们可以通过C++输入输出流解除绑定的方式进行加速,使其提升至C语言scanf和printf般的速度。

2.原理:

cin在为了与scanf保持同步,设置了一个缓冲区,为了保证各位混用两者的情况不会出错,利用这个缓冲区进行同步,不至于发生指针错误造成乱码,因此cin会牺牲一点点效率,而这一点点的效率,在大数据读取和运算的时候也会产生极大的影响,我们可以通过sync_with_stdio(false)的方式取消这个缓冲区,让cin变成和scanf一样的效率。

a) sync_with_stdio

这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起,默认情况为sync_with_stdio(ftrue),即开启。

b)cin.tie(0),cout.tie(0);

cin.tie(NULL);cout.tie(NULL);只解除的是C++运行库层面的对数据传输的绑定,stdin和stdout应该在更底层的操作系统层面有绑定,没有解除,也就是说,cin.tie(0)与cout.tie(0)的方式是继续松绑c++传输的效率。

因此我们可以在自己的代码中建立一个如此的模板:

#include<iostream>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
    /*
        写上你想写入的代码,并使用cin,cout输入输出
     */
 
    return 0;
}

也可以用宏定义的方式简写这段代码:

#define jiasu ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

在主函数进行引用即可。

 

根据最近的输出速度测试,分别在不同的平台进行存粹的输出测试,使用解除绑定的cout相对而言是最快的输出方式,而输入则因为某些受限的原因并不是最快的,为了使输入数据变快,请看下一章,快速读取。

 

备注:

1.NULL在C/C++语言中对应0,因此可以拿0代替NULL(空指针)

 

2.相关测试数据:

WINDWOS下[1e5的数据量]:

使用解除绑定的cout : 30.719000 秒 , 29.518000 秒 , 29.446000 秒

不使用解除绑定cout : 51.749000 秒 , 49.383000 秒 , 47.605000 秒

C++文件的printf : 84.962000 秒 , 76.131000 秒 , 77.639000 秒

C语言文件的printf : 29.776000 秒 , 29.327000 秒 , 29.862000 秒

 

LINUX系统下[1e5的数据量]:

使用解除绑定的cout : 0.199213 秒 , 0.195920 秒 , 0.195387 秒

不使用解除绑定cout : 0.199305 秒 , 0.188013 秒 , 0.199603 秒

C++文件的printf : 0.195575 秒 , 0.197582 秒 , 0.197400 秒

C语言文件的printf : 0.195144 秒 , 0.200245 秒 , 0.215732 秒

 

【在WINDOWS上面运行很久的程序在LINUX全部低于一秒钟结束】

 

LINUX系统下[1e7(一百万)的数据量]:

使用解除绑定的cout : 18.359119 秒 , 18.066489 秒 , 18.309879 秒

不使用解除绑定cout : 18.655116 秒 , 18.655820 秒 , 18.657697 秒

C++文件的printf : 18.354496 秒 , 18.592422 秒 , 18.312166 秒

C语言文件的printf : 18.463724 秒 , 18.475845 秒 , 18.495757 秒

 

数据来源: https://blog.dotcpp.com/a/60828



本文固定URL:https://www.dotcpp.com/course/122

第一章 数据结构入门
第二章 链表
第三章 栈
第四章 队列
第五章 从C语言到C++
第六章 串,数组,矩阵,广义表
第七章 树
第八章 图
第九章 算法—查找
第十章 算法—排序
第十一章 算法&竞赛,思维培养
第十二章 后记
Dotcpp在线编译      (登录可减少运行等待时间)