接下来对上篇中介绍的4种文件输入输出方法作相关的效率研究。
测试的方法还是相对简单的,随机生成数据data.in然后通过文件输入输出把data.in的内容全部输出到data.out并用时间相关函数计算运行时间。
运行时间计算方式如下
#include<time.h>
t=(double)clock()/CLOCKS_PER_SEC; //时间计算
fprintf(out,"Time Used : %f\n",t);
这样通过自带的一些函数既可以定量比较运行时间了。
数据生成器相关代码
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
char ranc(void)
{
return 'a'+rand()%('z'-'a'+1);
}
int main()
{
int i=1000000;
srand((unsigned int)time(NULL));
freopen("data.in","w",stdout);
while(i--){
printf("%c",ranc()); //生成1000000个无规则小写字母
}
printf("\n");
return 0;
}
fopen程序代码
#include<stdio.h>
#include<time.h>
int main()
{
FILE *fin=fopen("data.in","r");
FILE *fout=fopen("data.out","w");
FILE *out=fopen("TimeUsed.txt","a");
char c;
double t;
while(fscanf(fin,"%c",&c)!=EOF){
fprintf(fout,"%c",c);
}
t=(double)clock()/CLOCKS_PER_SEC;
fprintf(out,"Time Used By fopen: %f\n",t);
fclose(out);
fclose(fin);
fclose(fout);
remove("data.out");
return 0;
}
#include<stdio.h>
#include<time.h>
int main()
{
FILE *out=fopen("TimeUsed.txt","a");
char c;
double t;
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
while(scanf("%c",&c)!=EOF){
printf("%c",c);
}
t=(double)clock()/CLOCKS_PER_SEC;
fprintf(out,"Time Used By freopen: %f\n",t);
fclose(out);
fclose(stdout);
remove("data.out");
return 0;
}
cout代码
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
FILE *out=fopen("TimeUsed.txt","a");
double t;
char c;
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
while(cin >> c) cout << c;
cout << "\n";
t=(double)clock()/CLOCKS_PER_SEC;
fprintf(out,"Time Used By cout: %f\n",t);
fclose(out);
fclose(stdout);
remove("data.out");
return 0;
}
ofstream代码
#include<fstream>
#include<ctime>
using namespace std;
ifstream fin("data.in");
ofstream fout("data.out");
int main()
{
FILE *out=fopen("TimeUsed.txt","a");
double t;
char c;
while(fin >> c) fout << c;
fout << "\n";
t=(double)clock()/CLOCKS_PER_SEC;
fprintf(out,"Time Used By ofstream: %f\n",t);
fout.close();
fclose(stdout);
remove("data.out");
return 0;
}
程序每次运行后都会把运行时间写入TimeUsed.txt文件中,最后从该文件中统计运行时间即可。
接下来用批处理分别对每个程序运行10次,批处理代码如下
@echo off
for /l %%i in (1,1,10) do (
echo 第%%i数据测试
DataGenerator
echo 运行fopen
fopen
echo 运行freopen
freopen
echo 运行cout
cout
echo 运行ofstream
ofstream
echo 完成.
echo .
)
pause
程序很快就运行完毕了,但是在测试的过程中已经可以明显的发现批处理大部分时间都停留在了cout上。
接下来打开TimeUsed.txt
Time Used By fopen: 0.754000
Time Used By freopen: 0.862000
Time Used By cout: 6.538000
Time Used By ofstream: 0.804000
Time Used By fopen: 0.847000
Time Used By freopen: 0.802000
Time Used By cout: 6.806000
Time Used By ofstream: 0.805000
Time Used By fopen: 1.087000
Time Used By freopen: 0.836000
Time Used By cout: 6.492000
Time Used By ofstream: 0.960000
Time Used By fopen: 0.844000
Time Used By freopen: 0.889000
Time Used By cout: 6.011000
Time Used By ofstream: 0.776000
Time Used By fopen: 0.772000
Time Used By freopen: 0.749000
Time Used By cout: 6.158000
Time Used By ofstream: 0.753000
Time Used By fopen: 0.689000
Time Used By freopen: 0.813000
Time Used By cout: 6.133000
Time Used By ofstream: 0.359000
Time Used By fopen: 0.821000
Time Used By freopen: 0.745000
Time Used By cout: 6.279000
Time Used By ofstream: 0.787000
Time Used By fopen: 0.913000
Time Used By freopen: 0.789000
Time Used By cout: 6.465000
Time Used By ofstream: 0.836000
Time Used By fopen: 0.838000
Time Used By freopen: 0.818000
Time Used By cout: 6.366000
Time Used By ofstream: 0.820000
Time Used By fopen: 0.841000
Time Used By freopen: 0.861000
Time Used By cout: 5.987000
Time Used By ofstream: 0.811000
已经可以看到cout占的时间非常之长原因可能是因为cout函数的调用很复杂,为了适应所有数据类型的输出,可能在构造方面影响了效率。
接下来分析数据
#include<stdio.h>
#define AMOUNT 10
int main()
{
double t1,t2,t3,t4;
double s1=0,s2=0,s3=0,s4=0;
int i;
freopen("TimeUsed.txt","r",stdin);
freopen("DataStat1.txt","w",stdout);
for(i=1;i<=AMOUNT;i++){
scanf("Time Used By fopen: %lf\n",&t1);
scanf("Time Used By freopen: %lf\n",&t2);
scanf("Time Used By cout: %lf\n",&t3);
scanf("Time Used By ofstream: %lf\n",&t4);
s1+=t1;
s2+=t2;
s3+=t3;
s4+=t4;
}
printf("Average fopen time: %f\n",s1/AMOUNT);
printf("Average freopen time: %f\n",s2/AMOUNT);
printf("Average cout time: %f\n",s3/AMOUNT);
printf("Average ofstream time: %f\n",s4/AMOUNT);
return 0;
}
运行结果
Average fopen time: 0.840600
Average freopen time: 0.816400
Average cout time: 6.323500
Average ofstream time: 0.771100
更多的数据结果(舍弃cout)连续测试100次结果
Data amount: 100
Average fopen time: 0.645550
Average freopen time: 0.632950
Average ofstream time: 0.696410
Data amount: 100
Average fopen time: 0.654270
Average freopen time: 0.601150
Average ofstream time: 0.736960
关于其中的原理,作者表示并不清楚,欢迎大家对上述实验现象进行讨论!