2014-12-02 3 views
5

Um anzufangen, mache ich std::ios_base::sync_with_stdio(false). Ich habe die folgenden Teile des Codes, eine Million Zahlen aus einer Textdatei zu lesen (<input.txt >output.txt):Alternating cin/cout ist zu langsam?

int tests; 
cin >> tests; 
for (int i = 0; i < tests; ++i) { 
    int number; 
    cin >> number; 
    cout << number << "\n"; 
} 

und

int tests; 
cin >> tests; 
vector<int> numbers(tests); 
for (int i = 0; i < tests; ++i) { 
    cin >> numbers[i]; 
} 
for (int i = 0; i < tests; ++i) { 
    cout << numbers[i] << "\n"; 
} 

Natürlich in Wirklichkeit sind sie mehr als nur die gleichen Zahlen zu drucken. Das Problem ist, der erste Block dauert etwa 4 mal so lange (6,2 Sekunden gegenüber 1,8).

Das Umschreiben des gleichen Codes mit printf/scanf dauert 3 Sekunden in beiden Fällen. Was ist der Grund dafür?

+7

'cin' und' cout' sind [ 'tie()' d.] (Http://en.cppreference.com/w/cpp/io/basic_ios/ tie), die auf einer ruft 'flush()' auf der anderen Seite. –

+0

Soll 'sync_with_stdio' das nicht verhindern? – riv

+3

Nein. Das bricht die Verbindung zwischen 'cout' und' printf', sagen wir. Nicht zwischen "cout" und "cin". –

Antwort

3

Siehe std::basic_ios::tie, insbesondere aus folgenden Teilen:

A gebunden Strom ist ein Ausgangsstrom, der mit der Sequenz von dem Strompuffer gesteuert synchronisiert (rdbuf()), das heißt, flush() auf dem gebundenen Strom genannt vor jeder Eingabe-/Ausgabeoperation an *this.

Standardmäßig sind die Standarddatenströme cin, cerr und clog an cout gebunden. Ähnlich sind ihre breiten Gegenstücke wcin, wcerr und wclog an wcout gebunden.

Der Punkt ist, um sicherzustellen, dass in einem typischen interaktiven Programm, Dinge zu tun wie cout << "Enter something: "; cin >> something;, die Aufforderung tatsächlich auf dem Bildschirm erscheint, bevor das Programm für die Eingabe wartet.

Aber in Ihrem Fall, diese zusätzlichen flush() Anrufe besiegen die Ströme jeder Pufferung tun könnte, damit die Leistung zu verletzen.

Sie können die Bindung brechen mit cin.tie(nullptr);