printf mehr als 5-mal schneller als std::cout?
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
int main(int argc, char* argv[])
{
std::clock_t start;
double duration;
std::cout << "Starting std::cout test." << std::endl;
start = std::clock();
for (int i = 0; i < 1000; i++)
{
std::cout << "Hello, World! (" << i << ")" << std::endl;
}
duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
std::cout << "Ending std::cout test." << std::endl;
std::cout << "Time taken: " << duration << std::endl;
std::system("pause");
std::cout << "Starting std::printf test." << std::endl;
start = std::clock();
for (int i = 0; i < 1000; i++)
{
std::printf("Hello, World! (%i)\n", i);
std::fflush(stdout);
}
duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;
std::cout << "Ending std::printf test." << std::endl;
std::cout << "Time taken: " << duration << std::endl;
system("pause");
return 0;
}
Nun, hier sind die Zeiten für die ersten fünf Läufe:
- std::cout test: 1.125 s ; printf test: 0.195 s
- std::cout test: 1.154 s ; printf test: 0.230 s
- std::cout test: 1.142 s ; printf test: 0.216 s
- std::cout test: 1.322 s ; printf test: 0.221 s
- std::cout test: 1.108 s ; printf test: 0.232 s
Wie Sie sehen können, mit printf
und dann fflush
ing dauert etwa 5-mal weniger Zeit als mit std::cout
.
Obwohl ich es erwartet hatte mit std::cout
's <<
Betreiber zu sein, vielleicht ein wenig langsamer (fast minimal) , ich war nicht bereit für diesen großen Unterschied. Bin ich ein fairer test? Wenn ja, was macht dann der erste test so viel langsamer als die zweite, wenn Sie im wesentlichen genau die gleiche Sache?
- Haben Sie ermöglichen die Optimierung?
std::endl
in jeder iteration ist eine schlechte Idee. Verwenden'\n'
. Sie sind nicht die gleiche Sache.- Er hat flush in der printf-version zu sein, also, dass kann nicht wahr sein?
- mögliche Duplikate Frage keine Antwort auf meine wichtigste Frage,
**what makes** the first test so much slower than the second one...
ich.e warum genau ist die printf schneller? - es hängt davon ab, Realisierung: Für mich
cout
dann schnellerprintf
, aber nur wenn ich-std=c++0x
. - Kann es nicht eine einzige richtige Antwort, andere als die Qualität der Bibliothek Implementierung, die Sie verwenden. Dort wurden ähnliche Fragen wie das verlinkte. Lesen Sie es und Fragen es links zu.
- Beachten Sie, dass
std::cout << "Hello, World! (" << i << ")" << std::endl;
4 Funktionsaufrufe, währendprintf
ist nur einer. Versuchen Sieprintf
5 mal, wie mitcout
und sehen, was passiert. Dann werden Sie erkennen, wie viel von der Leistung scheitern wird durch die Funktion Aufrufe, und wie viel durch die Bibliothek selbst. - Deine aktuellen timings sind sinnlos wie der std::cout ist synchronisiert mit stdout und so viel "extra" arbeiten, um die Synchronisation zu gewährleisten. Wenn Sie entkoppelt werden Sie sehen eine Beschleunigung (es ist noch langsamer)
std::cout.sync_with_stdio(false);
- Es ist ziemlich unfair zu Spülen
stdout
für jedenprintf
. Ohne diestd::fflush(stdout);
dieprintf
Schleife viel schneller. Es ist zwar idiomatisch zu<< std::endl
ist es nicht idiomatisch zufflush(stdout)
. Ahnungslose C++ - Programmierer sind Sie wahrscheinlichcout
viel weniger uneffektiv, dannstdout
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für eine echte äpfel-zu-äpfel-Vergleich, re-schreiben Sie Ihren test, so dass die nur, was sich ändert, zwischen den test-Fällen ist die print-Funktion verwendet wird:
Mit, dass, werden Sie die Prüfung nichts, aber die Unterschiede zwischen den
printf
undcout
- Funktion aufruft. Sie wird nicht entstehen Unterschiede durch mehrere<<
Anrufe, etc. Wenn Sie versuchen, diese, ich vermute, dass Sie ein wesentlich anderes Ergebnis.std::cout.sync_with_stdio(false);
<<
Betreiber waren die wahrscheinlich Schuldigen, damit ich nicht die Mühe zeigt Beispiel-code, getestet, für andere Dinge. Sie könnte jedoch gelten die gleichen Allgemeinen Prinzip (eliminieren von Variablen zur Vereinfachung des Problems), das problem zu lösen, wenn der int-zu-string-Konvertierung der übeltäter war.<<
Anrufe alsprintf
Anrufe, es ist völlig angemessen zu vergleichen, Sie auf diese Weise. Es ist nicht realistisch zu vereinfachen, die Prüfung der Maße, die Sie haben.Versuchen Sie dies:
Dann bekomme ich:
Also den P2 Zeiten nicht ändern.
Aber Sie erhalten eine Verbesserung des P1-Zeiten (also std::cout) mit
std::cout.sync_with_stdio(false);
. Weil der code nicht mehr zu halten versucht, die beiden stream (std::cout stdout) synchronisiert. Was, wenn Sie schreiben Reine C++ und nur mit std::cout kein problem.verwenden
um zu verhindern, dass die Pufferung. viel schneller
Etwa 10 Jahren, Scott Meyers getestet, die Effizienz der iostream und scanf/printf. Hängt vom compiler und Umgebung, manchmal scanf/printf ist 20% schneller als die iostream -, manchmal sogar 200% schneller. Aber iostream war nie schneller als scanf/printf. Nach weiteren zwei Beispiele, scanf/printf ist immer noch schneller als die iostream.
Aber Meyers erklärte, dass "Auf ein wirklich nützliches Programm, gäbe es keine Unterschiede."
Laut Google"s Programmier-Stil([http://google-styleguide.googlecode.com/svn/trunk/cppguide.html%5D), Bäche sollten nicht verwendet werden, außer für die Protokollierung.
Ein Ersatz für die iostream-ist encapsule scanf/printf sich.
Ich habe nur ein Programmangebot von 1 computer, also auch nicht viel testen. Jedenfalls, std::cout ist viel schneller auf meinem bauen mit den genauen ausführlichen code. Ich bin mit Cpp14.
Ich denke nur bestimmte Personen haben ein pick für C++. Ja, C ist groß, die Sprache, aber logisch sehe ich nicht, wie printf () kann schneller sein als die std cout. Printf zu tun hat, Umwandlungen von void-Zeiger auf die Laufzeit. Cout bedeutet, dass zur compile-Zeit.
streambuf
virtuelle Funktion). Das ist sehr nützlich, wenn Sie eine Notwendigkeit, um die Umleitung des streams, aber verschwenderisch, wenn Sie ihn nicht benutzen.Versuchte ich diesen test auf meinem laptop mit Windows 10, WSL Ubuntu, CLion 2018, GCC. Keine Optimierung:
Ergebnisse:
TL;DR: Mit
std::ios_base::sync_with_stdio(false)
undstd::cin.tie(nullptr)
bringt beide Funktionen auf fast dem gleichen stand.