#A1003. 关于cin/cout/scanf/printf输入输出时间测试

关于cin/cout/scanf/printf输入输出时间测试

背景

对比 cin cout scanf printf的运行时间

题目描述

输入n个数,输出n个数,查看运行时间

输入

第一行,一个数n 第二行,n个整数

输出

n行,每行一个整数

样例 Samples

3
1 2 3
1
2
3

数据范围说明

测试点 数据范围
131-3 1N1001≤N≤100
464-6 100N103100≤N≤10^3
797-9 103N10410^3≤N≤10^4
101210-12 104N10510^4≤N≤10^5
131513-15 105N10610^5≤N≤10^6
161716-17 106N10710^6≤N≤10^7

其中 第15个测试点NN=10000001000000

第16个测试点NN=51299965129996

第17个测试点NN=99350009935000

限制

时间限制:1000ms 空间限制:256M

测试代码说明:

注意观察比较以下每种方法的运行时间。

方法一:常规输入,超时

#include <bits/stdc++.h>
using namespace std;
int n;
int a;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;	
		cout<<a<<endl;
	}
	return 0;
}

方法二:关闭输入同步语句,但使用endl换行,超时

#include <bits/stdc++.h>
//#define endl "\n"
using namespace std;
int n;
int a;
int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;	
		cout<<a<<endl;
	}
	return 0;
}

方法三:使用C语言的输入输出,略微超时

#include <bits/stdc++.h>
using namespace std;
int n;
int a;
int main(){
	scanf("%d",&n); //cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d",&a); //cin>>a;	
		printf("%d\n",a); //cout<<a<<endl;
	}
	return 0;
}

方法四:关闭输入同步语句,使用“\n”换行,通过AC

#include <bits/stdc++.h>
#define endl "\n"//使用“\n”代替endl
using namespace std;
int n;
int a;
int main(){
	ios::sync_with_stdio(false);//关闭cin cout输入输出和scanf printf的同步状态
    cin.tie(0);
    cout.tie(0);
    //注意:以下代码不允许再使用scanf printf语句
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a;	
		cout<<a<<endl;//cout<<a<<"\n";
	}
	return 0;
}

方法五:手写快读模式 手写快读相对比以上的输入方法要快速,但代码比较繁琐,现在的竞赛中越来越偏向于侧重考察思维能力和算法能力,对于这种卡输入输出的要求越来越少了,所以一般也不常用。

#include <bits/stdc++.h>
using namespace std;
int n;
int a;
inline int read(){
    register int x = 0, t = 1;
    register char ch=getchar(); // 读入单个字符到寄存器
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            t=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);  // 移位与异或
      	// 第十行可以换成 x = x * 10 + ch - '0'
        ch=getchar();
    }
    return x*t;
}
inline void write(int x)
{
    if(x<0){
    	putchar('-');
		x=-x;
	}
    if(x>9) 
		write(x/10);
    putchar(x%10+'0');
}
int main(){
	n=read();//cin>>n;
	for(int i=1;i<=n;i++){
		a=read();//cin>>a;	
		write(a);//cout<<a<<endl;
		printf("\n");
	}
	return 0;
}

以上五种输入方法后三个测试点的运行时间对比(实际运行时间根据不同环境和不同时间会有所不同,主要是对比各个输入方法的快慢):

测试点 方法1 方法2 方法3 方法4 方法5
14 757ms 673ms 126ms 109ms 38ms
15 1853ms 1532ms 358ms 267ms 87ms
16 ≥3013ms ≥3009ms 1196ms 883ms 396ms

总结

根据以上测试可以看出,如果输入输出数据合计在1000010000次以内,可以任意选择你喜欢的方式输入输出,如果超过10000就需要注意输入输出的选择,根据题目要求和个人习惯选择方法3~5。

另外几点说明:

1、方法2和4,使用了io::sync_with_stdio(false)语句关闭了和scanf printf的同步,所以不能在代码中出现scanf printf混用的情况;

2、scanf和printf属于c语言的输入输出方式,cin和cout属于c++新增的输入输出方法;

3、输入换行时候"endl"比"\n"会消耗更多时间,所以在输出数据比较多的时候请使用"\n",输出数据不大的情况下,可以根据个人习惯使用。如果在没有输出“换行”的情况下,方法2,3,4的运行时间基本上差不多;

4、现在的竞赛中一般方法3和4都能满足题目需求了,关于方法5虽然很快,但是由于代码繁琐,一不小心反而容易出错,所以实际使用的并不多。