Ich möchte eine Datei in eine Zeichenfolge lesen. Ich suche nach verschiedenen Wegen, wie man es effizient macht.
Verwenden eines Zeichenpuffers fester Größe *
Ich habe eine Antwort erhalten von Tony, was einen 16-kb-Puffer erzeugt und in diesen Puffer liest und den Puffer anhängt, bis nichts mehr zu lesen ist. Ich verstehe, wie es funktioniert und ich fand es sehr schnell. Was ich nicht verstehe ist, dass in den Kommentaren dieser Antwort gesagt wird, dass auf diese Weise alles zweimal kopiert wird. Aber wie ich es verstehe, passiert es nur in der Erinnerung, nicht von der Festplatte, also ist es fast unbemerkt. Ist es ein Problem, dass es aus dem Puffer in die Zeichenfolge im Speicher kopiert?
Verwenden von istreambuf_iterator
Die andere Antwort Ich habe verwendet istrebuf_iterator. Der Code sieht schön und minimal aus, aber er ist extrem langsam. Ich weiß nicht, warum es passiert. Warum sind diese Iteratoren so langsam?
Verwenden von memcpy ()
Für diese Frage erhielt ich Kommentare, dass ich Memcpy () verwenden sollte, da es die schnellste native Methode ist. Aber wie kann ich memcpy () mit einer Zeichenfolge und einem ifstream-Objekt verwenden? Soll ifstream nicht mit einer eigenen Lesefunktion arbeiten? Warum zerstört die Verwendung von memcpy () die Portabilität? Ich suche nach einer Lösung, die sowohl mit VS2010 als auch mit GCC kompatibel ist. Warum sollte memcpy () nicht mit diesen arbeiten?
+ Jeder andere effiziente Weg möglich?
Was empfehlen Sie, welche Shell ich verwende, für kleine & lt; 10 MB Binärdateien?
(Ich wollte diese Frage nicht in Teilen aufteilen, da ich mich mehr für den Vergleich zwischen den verschiedenen Möglichkeiten interessiere, wie ich einen ifstream in eine Zeichenkette einlesen kann)
es passiert nur im Speicher, nicht von der Festplatte, so ist es fast unbemerkt
Das ist in der Tat richtig. Dennoch kann eine Lösung, die das nicht tut, schneller sein.
Warum sind diese Iteratoren so langsam?
Der Code ist langsam, nicht wegen der Iteratoren, sondern weil die Zeichenfolge nicht weiß, wieviel Speicher zuzuweisen ist: Die istreambuf_iterator
s kann nur einmal durchlaufen werden, sodass die Zeichenfolge im Wesentlichen gezwungen wird, wiederholte Verkettungen mit resultierenden Speicherumverteilungen durchzuführen , die sehr langsam sind.
Mein Lieblings-Einzeiler, von eine andere Antwort streamt direkt aus dem zugrunde liegenden Puffer:
%Vor% Auf neueren Plattformen wird dies in der Tat den Puffer vorab reservieren. Dies führt jedoch immer noch zu einer redundanten Kopie (von stringstream
bis zur letzten Zeichenfolge).
Der allgemeinste Weg wäre wahrscheinlich die Antwort mit dem
istreambuf_iterator
:
Obwohl die genaue Leistung sehr von der Implementierung abhängt, ist es das sehr unwahrscheinlich, dass dies die schnellste Lösung ist.
Eine interessante Alternative wäre:
%Vor% Das könnte sehr schnell gehen, wenn die Implementierung einen guten Job gemacht hat
das operator<<
, das du benutzt, und wie es die Zeichenkette innerhalb der
%Code%. Einige frühere Implementierungen (und vielleicht noch mehr
auch die jüngsten) waren sehr schlecht.
Im Allgemeinen hängt die Leistung mit istringstream
davon ab, wie
Effizient die Implementierung ist in einer wachsenden Reihe; die Umsetzung
kann nicht bestimmen, wie groß es anfangs sein soll. Sie möchten vielleicht
vergleiche den ersten Algorithmus mit dem gleichen Code mit std::string
anstelle von std::vector<char>
, oder wenn Sie eine gute Schätzung der
maximale Größe, mit std::string
, oder etwas wie:
reserve
kann nicht aus einer Datei lesen, und mit einem guten Compiler wird es nicht sein
So schnell wie memcpy
verwenden (mit den gleichen Datentypen).
Ich neige dazu, die obige zweite Lösung mit dem std::copy
auf der
<<
, aber das ist teilweise aus historischen Gründen; ich habe mich daran gewöhnt
tue dies (mit rdbuf()
), bevor die STL zum Standard hinzugefügt wurde
Bibliothek. Vielleicht möchten Sie experimentieren
istrstream
und ein vorher zugeordneter Puffer (vorausgesetzt, Sie können ein
geeignete Größe für den Puffer).
Tags und Links string c++ gcc visual-studio istream