四种读入方式的效率对比

序:
之前在一篇关于vector的push_back和resize()等方式读取数据的效率对比中,我们发现最快的是通过读入优化。这次将测试四种读入方式的效率对比:
两种读入优化,scanf与fscanf。
测试数据采用随机生成的10000000个int型整数,在windows环境下运行。
测试时间由time.h中的函数计算。


四种读取方式:

int input;
inline void read1(int &curr)
{
    static char c;
    c = getchar();
    while(c < '0' || c > '9')   c = getchar();
    while(c >= '0' && c <= '9')
    {
        curr = curr*10+c-'0';
        c = getchar();
    }
    return ;
}

inline void read2()
{
    static char c;
    //int input = 0;
    input = 0;
    c = getchar();
    while(c < '0' || c > '9')   c = getchar();
    while(c >= '0' && c <= '9')
    {
        input = input*10+c-'0';
        c = getchar();
    }
    //return input;
    return ;
}

void Init1()//传地址
{
    freopen("test.in", "r", stdin);
    int n = 0, i;
    int startTime = clock();
    read1(n); 
    for(unsigned i = 0; i != n; ++i)
    {
        read1(m[i]);
    }
    int endTime = clock();
    ans[1] += (double)(endTime-startTime)/CLOCKS_PER_SEC;
    //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << endl;
    fclose(stdin);
}

void Init2()//利用全局变量
{
    freopen("test.in", "r", stdin);
    //freopen("test.out", "w", stdout);
    int n = 0, i, j;
    int startTime = clock();
    read2();
    n = input; 
    for(unsigned i = 0; i != n; ++i)
    {
        read2();
        m[i] = input;
    }
    int endTime = clock();
    ans[2] += (double)(endTime-startTime)/CLOCKS_PER_SEC;
    //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << endl;
    fclose(stdin);
    //fclose(stdout);
}

void Init3()//文件读入
{
    int i, n;
    FILE *fp = fopen("test.in", "rb");
    int startTime = clock();
    fscanf(fp, "%d", &n);
    for(unsigned i = 0; i != n; ++i)
    {
        fscanf(fp, "%d", &m[i]);
    }
    int endTime = clock();
    ans[3] += (double)(endTime-startTime)/CLOCKS_PER_SEC;
    //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << "s" <<endl;
    fclose(fp);
}

void Init4()//普通
{
    int i, n;
    freopen("test.in", "r", stdin);
    int startTime = clock();
    scanf("%d", &n);
    for(unsigned i = 0; i != n; ++i)
    {
        scanf("%d", &m[i]);
    }
    int endTime = clock();
    ans[4] += (double)(endTime-startTime)/CLOCKS_PER_SEC;
    //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << "s" <<endl;
    fclose(stdin);
}

很显然后两种相对较慢,所以分两组进行测试:(1,2)和(3,4)。


对于两种读入优化,我们的测试方法是循环50次算总时间与平均时间。
结果如下:
这里写图片描述
看来相比于传地址,设置一个全局变量还是更快一些。平均快18ms。


对于3,4的读入,我们循环10次。
结果如下:
38.773s
37.575s
看得出相比于文件读入,scanf还是更胜一筹。


那么小数据哪?

测试5000个int型整数的读入时间(循环10次)。
结果如下:
这里写图片描述

结果依然。


100个(10次)。
这里写图片描述
突然fscanf变得很快。


总而言之,小数据读入优化并没有什么用,当总数据超过百万的时候会体现出较大差距
(100000*10的时候:
0.059000 0.005900
0.057000 0.005700
0.393000 0.039300
0.372000 0.037200)读入时间相差300+ms
十万时是30+ms。若达到千万那么前两种只是后两种的零头,差距巨大(3.3s)。
以此可见,读入越大的数据的时候读入优化越重要,一个读入优化可能就能将TLE的程序AC(前提是你算法是对的…)。

箜瑟_qi 2017.04.15 14:19

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值