对于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] add binary 二进制加法
Given two binary strings, return their sum (also a binary string). For example,a ="11"b =& ...
- Substrings Sort string 基本操作
You are given nn strings. Each string consists of lowercase English letters. Rearrange (reorder) the ...
- ios webapp调试神器MIHTool
android平台有直接用chrome beta就可以调试,具体操作办法可以查看这篇教程<Android 设备 Chrome 远程调试>Mac的高富帅直接可以用safari提供“web检查 ...
- eclipse配置文件内存设置
1.-Xms64m -Xmx128m 2.配置文件的修改 http://wenku.baidu.com/link?url=spM-qCe0qHdhiykzwuzp-vBtcQrVtAzYiWe8uex ...
- 单选按钮radio与文字如何对齐?
布局如下: <input type="radio" value="立即发送" name="a_1">立即发送 <input ...
- [BZOJ1982][POJ1740][Spoj 2021]Moving Pebbles|解题报告
这道题的题意BZ和POJ上的都不大清楚... 大概就是给出n堆石子,以及初始每堆石子的个数 两个玩家交替操作,每个操作可以任意在一堆中取任意多的石子 然后再从这堆里拿若干个石子放到某个当前还存在的堆里 ...
- Google Intern
申请 事情应该从去年(2013)说起,好基友从百度离职跳到了Google,回学校打印本科成绩单,然后晚上在scuacm群里,结果Dr. zuo问我想去实习么,正好有学长可以内推. 于是乎写了简历,然后 ...
- Swift 闭包(六)
http://blog.csdn.net/huangchentao/article/details/32714185 闭包 Closures 1.闭包表达式 闭包表达式是一种利用简单语法构建内联包的方 ...
- python实战===一行代码就能搞定的事情!
打印9*9乘法表: >>> print( '\n'.join([' '.join(['%s*%s=%-2s' % (y,x,x*y) for y in range(1,x+1)]) ...
- Linux内核:关于中断你需要知道的【转】
转自:http://blog.csdn.net/duqi_2009/article/details/38009717 1.中断处理程序与其他内核函数真正的区别在于,中断处理程序是被内核调用来相应中断的 ...