对于scanf和cin的输入输出速度的验证
本文为https://www.byvoid.com/zhs/blog/fast-readfile的验证性文章
---------------------------------------------------------------------------
首先生成一千万个随机数
#include<cstdio>
#include<ctime>
#include<cstdlib>
int main ()
{
freopen("data.txt","w",stdout);
srand(time());
for(int i=;i<;i++)
printf("%d ",rand());
return ;
}
我用重定向把数据导出到"data.txt"了。
然后,用scanf来读取数据,并计时
#include<cstdio>
#include<ctime>
int a[];
int main ()
{
int start = clock();
freopen("data.txt","r",stdin);
for(int i=;i<;i++)
scanf("%d",&a[i]);
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
}
执行之后,使用时间为1.18s,相比于原文的2.01秒,缩短了一截,然后测试一下使用cin输入的情况,代码如下:
#include<cstdio>
#include<ctime>
#include<iostream>
int a[];
int main ()
{
int start = clock();
freopen("data.txt","r",stdin);
for(int i=;i<;i++)
std::cin>>a[i];
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
}
cin的使用时间为4.67s,比scanf更长,但是相比于原文的6.38s还是短得多。
然后取消cin与stdin之间的同步之后,代码如下:
#include<cstdio>
#include<ctime>
#include<iostream>
int a[];
int main ()
{
int start = clock();
std::ios::sync_with_stdio(false);
freopen("data.txt","r",stdin);
for(int i=;i<;i++)
std::cin>>a[i];
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
}
时间大幅缩短,为1.24s,与scanf很接近了。
然后按原文测试读入整个文件,代码如下:
#include<iostream>
#include<ctime>
#include<cstdio>
const int MAXN = ;
const int MAXS = **;
int numbers[MAXN];
char buf[MAXS]; void analyse(char *buf, int len =MAXS)
{
int i;
numbers[i=]=;
for(char *p=buf;*p && p-buf<len;p++)
if(*p == ' ')
numbers[++i]=;
else
numbers[i]=numbers[i]*+*p-'';
} void fread_analyse()
{
freopen("data.txt","rb",stdin);
int len = fread(buf,,MAXS,stdin);
buf[len]='\0';
analyse(buf,len);
} int main ()
{
int start = clock();
fread_analyse();
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
return ;
}
时间如原文一般,大幅缩短,我这里测试得到0.37s,使用read测试,代码如下:
#include<iostream>
#include<ctime>
#include<cstdio>
#include<unistd.h>
#include<fcntl.h>
const int MAXN = ;
const int MAXS = **;
int numbers[MAXN];
char buf[MAXS]; void analyse(char *buf, int len =MAXS)
{
int i;
numbers[i=]=;
for(char *p=buf;*p && p-buf<len;p++)
if(*p == ' ')
numbers[++i]=;
else
numbers[i]=numbers[i]*+*p-'';
} void read_analyse()
{
int fd = open("data.txt",O_RDONLY);
int len = read(fd,buf,MAXS);
buf[len]='\0';
analyse(buf,len);
} int main ()
{
int start = clock();
read_analyse();
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
return ;
}
测试时间为0.31s,有所进步,不过不是非常明显。
调用mmap,代码如下:
#include<iostream>
#include<ctime>
#include<cstdio>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
const int MAXN = ;
const int MAXS = **;
int numbers[MAXN];
char buf[MAXS]; void analyse(char *buf, int len =MAXS)
{
int i;
numbers[i=]=;
for(char *p=buf;*p && p-buf<len;p++)
if(*p == ' ')
numbers[++i]=;
else
numbers[i]=numbers[i]*+*p-'';
} void mmap_analyse()
{
int fd = open("data.txt",O_RDONLY);
int len = lseek(fd,,SEEK_END);
char *mbuf = (char *) mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,);
analyse(mbuf,len);
} int main ()
{
int start = clock();
mmap_analyse();
printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
return ;
}
达到0.49s,与原文不符(原文中使用mmnp耗时更短,在我的测试中,耗时变长了),可能是代码与原作者的不一样,原作者只给出一部分代码,而测试需要写出完整的代码,可能我写的代码有问题。
以上测试结果在腾讯云上进行,因为原作者当时的硬件条件可能比不上我所使用的环境,我在树莓派 3B和我自己的电脑上测试了一下,所有平台硬件信息如下:
| 平台/硬件和软件信息 | Cent OS | Raspberry | Windows |
| CPU | 1 Core | Broadcom BCM2837 1.2GHz | intel Core 5200u 2.2GHz |
| RAM | 1GB | 1GB | 12GB |
| Gcc | 4.8.5 | 4.9.2 | 5.3.0 |
PS: 这里忽略了硬盘的性能,理论上来说,硬盘的性能肯定能影响读写速度,只是没有较好的方法比较三个平台的硬盘性能,只能作罢。不过在下面的表中我对比了我自己电脑上在Windows环境下和Linux环境下的情况。相较于原文,舍去VS的比较信息,全部使用了GNU/GCC.
测试结果如下
| 方法/平台/耗时(s) | Cent OS | Raspberry | Windows(本机) | Ubuntu(本机) |
| scanf | 1.180 | 14.786 | 4.488 | 1.158 |
| cin | 13.026 | 61.255 | 13.026 | 4.309 |
| cin(取消同步) | 1.240 | 7.694 | 8086 | 1.135 |
| fread | 0.37 | 3.503 | 0.327 | 0.284 |
| read | 0.31 | 2.975 | 0.370 | 0.285 |
| mmap | 0.49 | 5.945 | NULL | 0.447 |
在同等硬件条件下,Windows比Linux慢得多,在同等环境下,硬件好的自然快,树莓派充分证明了这一点。
对于scanf和cin的输入输出速度的验证的更多相关文章
- scanf和cin的差异
scanf和cin的差异 引例:http://www.cnblogs.com/shenben/p/5516996.html 大家都知道,在C++中有两种输入.输出方式—scanf和cin,但是,它们之 ...
- 关于scanf与cin哪个快的问题
一开始入c++的时候成天跑cin,cout 直到有一天用cin,cout超时 才知道scanf比cin快的多 但是后来又听说加了ios::sync_with_stdio(false);的cin跟飞一样 ...
- 关于scanf 与 cin gets(),getline()......输入输出字符串的区别
很对人对于字符串的输入输出一直是比较模糊的,今天总结一下几个常用的输入流符号对于输入字符串时的区别: 1.scanf(),首先 它遇到空格或回车键(\n)就会结束,并且会将回车符算入字符串中: 2.c ...
- c++使用cin、cout与c中使用scanf、printf进行输入输出的效率问题
在c++中,我们使用cin和cout进行输入输出会比用scanf和printf更加简洁和方便,但是当程序有大量IO的时候,使用cin和cout进行输入输出会比用scanf和printf更加耗时, 在数 ...
- mac 下 sublime text 运行c++/c 不能使用scanf/cin
{ "cmd": ["g++", "${file}", "-o", "${file_path}/${file_ ...
- scanf 和cin 的区别
笔试的时候经常遇到突然string s;cin>>s; 有的时候编译会错误,不知道为什么. 今天在练习枚举类型的时候,也遇到这样一个问题. enum weekday{Monday,Tues ...
- scanf 与 cin 的区别
在论坛上看到有人提出一个如下的问题,在此总结一下. 原问题: http://topic.csdn.net/u/20110414/22/90d0606c-9876-48e4-9b69-bd8bd8a41 ...
- cin 和scanf,scanf比cin快很多
//#include <iostream> #include <stdio.h> //#include <fstream> //using namespace st ...
- scanf和cin性能的比较
我的实验机器配置是: 处理器:Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz 2.40GHz 随机访问存储器:4.00GB 操作系统:Windows10 集成开发环境 ...
随机推荐
- [Leetcode] Palindrome number 判断回文数
Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. S ...
- 【CF Round 434 B. Which floor?】
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- 如何配置开源中国Maven库以加快依赖包下载速度
有时有某些地方由于网络问题,访问maven主仓库比较慢,甚至有可能无法下载某些jar包,此时可以把开源中国Maven库配置到settings.xml文件中,加快依赖包的下载速度. 具体如何配置? 在m ...
- bzoj1914 [Usaco2010 OPen]Triangle Counting 数三角形 计算机和
[Usaco2010 OPen]Triangle Counting 数三角形 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 526 Solved: 2 ...
- java 多线程 原子性
原子性 原子性:原子操作是不能被线程调度机制中断的操作,一旦操作开始,那么它就一定可以在可能发生的“上下文切换”之前(切换到其他线程执行)执行完毕. 依赖原子性是很棘手且很危险的,除非你是并发专家,否 ...
- sql异常-The used SELECT statements have a different number of columns
两个或多个select查询进行union时,查询的列不对应.两个select进行union时,两个select的查询出的列必须相对应.
- C语言编译各过程
1.预处理 此阶段主要完成#符号后面的各项内容到源文件的替换,往往一些莫名其妙的错误都是出现在头文件中的,要在工程中注意积累一些错误知识. (1).#ifdef等内容,完成条件编译内容的替换 (2). ...
- java深入解析
具体内容安排如下: Java Collections Framework概览 对Java Collections Framework,以及Java语言特性做出基本介绍. Java ArrayList源 ...
- rest service技术选型
MySql workbench下载 http://dev.mysql.com/downloads/workbench/ 最好的8个 Java RESTful 框架 http://colobu.com/ ...
- bzoj 1076 状压DP
我们设w[i][s]为当前到第i关,手中的物品为s的时候,期望得分为多少,其中s为二进制表示每种物品是否存在. 那么就比较容易转移了w[i][s]=(w[i-1][s']+v[j]) *(1/k),其 ...