1. 程式人生 > >ACM學習歷程3——C與C++輸入輸出效率的問題

ACM學習歷程3——C與C++輸入輸出效率的問題

在上面一個博文中介紹了在演算法設計大賽中會用到的各類輸入輸出形式,涉及到的主要語句是C中的scanfprintf以及C++中的cincout。事實上,在某些程式設計題中,有時會出現Time Limited的錯誤。當出現這種錯誤時,原因無非以下幾種:程式中出現了死迴圈使得程式無法在規定的時間內完成;演算法設計的過於複雜,使用了過多的迴圈使得程式步執行的次數過多;不合理語句的使用,包括輸入輸出語句等等。這裡說說CC++的輸入輸出效率,在不做任何修改的情況下,CC++的效率是不一樣的,先來做個簡單的測試。

用下面的程式碼生成100000個測試資料,資料儲存在Data.in檔案中。

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
    ofstream fout("Data.in");
    for(int i=0; i<100000; i++)
        fout<<i<<endl;
    fout.close();
    return 0;
}

Windows下簡單的測試一下,CC++讀取耗時:

C++

#include<iostream>
#include<fstream>
#include<ctime>
using namespace std;
int main()
{
    int start = clock();
    int num;
    freopen("Data.in","r",stdin);//重定向
    while(cin >> num)
    {

    }
    printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
    fclose(stdin);
    return 0;
}

執行以上程式,cin讀取這100000個數據的時間約為0.425秒。

C:

#include<fstream>
#include<ctime>
#include<cstdio>
using namespace std;
int main()
{
    int start = clock();
    int num;
    freopen("Data.in","r",stdin);//重定向
    while(scanf("%d",&num)!=EOF)
    {

    }
    printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
    fclose(stdin);
    return 0;
}

執行以上程式,scanf讀取這100000個數據的時間約為0.03秒。

當然,上面兩段程式碼的執行時間在我自己的電腦上測試大概就是這個樣子,實際的執行時間跟計算機的效能有關係同時也跟編譯器有關,我說使用的編譯器是Dev-C++4.9.9.1版本。但是不管怎麼說C的輸入確實比C++要快得多。那是不是C++的輸入速度就一定比C慢呢?後來我知道了C++有一條語句:std::ios::sync_with_stdio(false)可以加快輸入速度,我們先加入這條語句到上面的第一個測試程式碼中,看看時間是否會變快。

#include<iostream>
#include<fstream>
#include<ctime>
using namespace std;
int main()
{
    int start = clock();
    int num;
    freopen("Data.in","r",stdin);//重定向
    std::ios::sync_with_stdio(false);
    while(std::cin >> num)
    {

    }
    printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
    fclose(stdin);
    return 0;
}

執行時間0.136秒,看來時間確實變快了一些。原因何在,在預設情況,cinstdin總是保持同步的,也就是說這兩種方法可以混用,而不必擔心檔案指標混亂,同時coutstdout也一樣,兩者混用不會出現輸出順序錯亂的問題。正因為這個相容性的特性,導致cin有許多額外的開銷,使用std::ios::sync_with_stdio(false)語句這樣就可以取消cinstdin的同步了,此時cin的效率也會相應的提升一些。此外在Cscanfprintf是格式化的輸入輸出效率較高,C++中的cincout是輸入流和輸出流,雖然在使用的過程中我們可以不管資料的型別但是效率低一點。