一、背景
做题的时候,经常写读入优化,而读入优化的核心是“getchar”,它比scanf快多了。
我不禁想,有没有“putchar”呢?有。那么有没有输出优化呢?它和printf和cout谁更快呢?
于是就写下了这个验证程序。
二、验证
在网上搜了一下,主要有两种输出优化。
第一种是比较常见的:
inline void Putint_usual(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) Putint_usual(x/10);
putchar(x%10+'0');
}
第二种是使用数组的的:
inline void Putint_array(int x)
{
int buf[30]={0};
if (x<0) putchar('-'),x=-x;
buf[0]=0;
while (x) buf[++buf[0]]=x%10,x/=10;
if (!buf[0]) buf[0]=1,buf[1]=0;
while (buf[0]) putchar('0'+buf[buf[0]--]);
}
以上两种的基本思路就是把这个数的每一位都求出来,然后依次用putchar输出。
除此之外,c语言还自带有printf,c++还有cout。
于是我写了一个程序。
#include<cstdio>
#include<ctime>
#include<algorithm>
#include<windows.h>
#include<iostream>
using namespace std;
inline void pri(int p)
{
printf("%d",p);
}
inline void Putint_usual(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) Putint_usual(x/10);
putchar(x%10+'0');
}
inline void Putint_array(int x)
{
int buf[30]={0};
if (x<0) putchar('-'),x=-x;
buf[0]=0;
while (x) buf[++buf[0]]=x%10,x/=10;
if (!buf[0]) buf[0]=1,buf[1]=0;
while (buf[0]) putchar('0'+buf[buf[0]--]);
}
inline void c(int p)
{
cout<<p;
}
double t1,t2,ans1,ans2,ans3,ans4;
int main()
{
const int T=300000;//测试多少个数
freopen("asdfghjkl.txt","w",stdout);
t1=clock();
for(int i=1;i<=T;i++) Putint_array(i);
t2=clock();
ans1+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) Putint_usual(i);
t2=clock();
ans2+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) pri(i);
t2=clock();
ans3+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) c(i);
t2=clock();
ans4+=(t2-t1)/1000;
system("cls");
fclose(stdout);
freopen("out.txt","w",stdout);
printf("When T=%d: \n",T);
printf("Putint_array took %.2lf second\n",ans1);
printf("Putint_usual took %.2lf second\n",ans2);
printf("printf took %.2lf second\n",ans3);
printf("cout took %.2lf second\n",ans4);
}
代码解释:
clock();//取得当前的时间,单位是ms。要算一段时间,只需要用 [(结束的时间)-(开始的时间)],即可,因为单位是ms,所以除以1000,让单位转化成s。需要#include<ctime>或者#include<time.h>
system("cls");//清屏指令,需要#include<windows.h>头文件
补充说明:
1.为了公平起见,四种方式都写在了内链函数里。避免调用函数的时间对程序产生影响。
2.四种方式都非常的不稳定,只运行一次不可信。
3.T是可以更改的
4.因为是比较输出效率,所以说必须输出出来,但是满屏都是数字在飞,特别烦人,所以加了清屏指令。
下面T=30000和T=10000000为例,输出结果为:
When T=300000:
Putint_array took 0.05 second
Putint_usual took 0.03 second
printf took 0.11 second
cout took 0.08 second
When T=10000000:
Putint_array took 1.97 second
Putint_usual took 1.51 second
printf took 3.77 second
cout took 2.80 second
所以说,相较起来,常规的输出优化是最快的,而cout擅长输出小数据,比如把输入i换成输出一个很大的数字来看看?
#include<cstdio>
#include<ctime>
#include<algorithm>
#include<windows.h>
#include<iostream>
using namespace std;
inline void pri(int p)
{
printf("%d",p);
}
inline void Putint_usual(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) Putint_usual(x/10);
putchar(x%10+'0');
}
inline void Putint_array(int x)
{
int buf[30]={0};
if (x<0) putchar('-'),x=-x;
buf[0]=0;
while (x) buf[++buf[0]]=x%10,x/=10;
if (!buf[0]) buf[0]=1,buf[1]=0;
while (buf[0]) putchar('0'+buf[buf[0]--]);
}
inline void c(int p)
{
cout<<p;
}
double t1,t2,ans1,ans2,ans3,ans4;
int main()
{
const int T=5000000;//测试多少个数
const long INF=(1<<32)-1;
freopen("asdfghjkl.txt","w",stdout);
t1=clock();
for(int i=1;i<=T;i++) Putint_array(i);
t2=clock();
ans1+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) Putint_usual(INF);
t2=clock();
ans2+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) pri(INF);
t2=clock();
ans3+=(t2-t1)/1000;
system("cls");
t1=clock();
for(int i=1;i<=T;i++) c(INF);
t2=clock();
ans4+=(t2-t1)/1000;
system("cls");
fclose(stdout);
freopen("out.txt","w",stdout);
printf("When T=%d: \n",T);
printf("Putint_array took %.2lf second\n",ans1);
printf("Putint_usual took %.2lf second\n",ans2);
printf("printf took %.2lf second\n",ans3);
printf("cout took %.2lf second\n",ans4);
}
结果:
When T=5000000:
Putint_array took 1.11 second
Putint_usual took 0.16 second
printf took 0.88 second
cout took 1.11 second
综上:还是使用输出优化吧!
注意:
以上结果是输出在了Freopen里,但是如果不要Freopen,直接在cmd里输出,会得到完全不一样的结果!(输出在cmd时,printf较快!)