C fgets gegen fgetc zum Lesen der Zeile

9

Ich muss eine Textzeile lesen (mit einem Zeilenende versehen), ohne Annahmen über die Länge zu machen. So sehe ich jetzt Möglichkeiten:

  • Verwenden Sie fgets und prüfen Sie jedes Mal, ob das letzte Zeichen ein Zeilenumbruch ist und kontinuierlich an einen Puffer angehängt wird
  • Lies jedes Zeichen mit fgetc und gelegentlich mit realloc dem Puffer

Intuition sagt mir, dass die fgetc Variante möglicherweise langsamer ist, aber dann sehe ich nicht, wie fgets es tun kann, ohne jedes Zeichen zu prüfen (auch meine Intuition ist nicht immer so gut). Die Linien sind ziemlich groß, deshalb ist die Leistung wichtig.

Ich würde gerne die Vor- und Nachteile jedes Ansatzes kennen. Vielen Dank im Voraus.

    
nc3b 03.03.2011, 20:58
quelle

5 Antworten

1

Ich schlage vor, fgets() in Verbindung mit dynamischer Speicherzuweisung zu verwenden - oder Sie können die Schnittstelle zu % co_de untersuchen % im POSIX 2008-Standard und auf neueren Linux-Rechnern verfügbar. Das macht die Speicherzuweisung für Sie. Sie müssen sowohl die Pufferlänge als auch die Adresse im Auge behalten, damit Sie sich selbst eine Struktur für die Verarbeitung der Informationen erstellen können.

Obwohl getline() auch funktioniert, ist es marginal fiddlier - aber nur marginal so. Unter den Deckeln verwendet es dieselben Mechanismen wie fgetc() . Die Interna können möglicherweise eine schnellere Operation ausnutzen - analog zu fgets() -, die nicht verfügbar sind, wenn Sie strchr() direkt aufrufen.

    
Jonathan Leffler 03.03.2011, 21:05
quelle
2

Bietet Ihre Umgebung die Funktion getline(3) ? Wenn ja, würde ich sagen, gehen Sie dafür.

Der große Vorteil, den ich sehe, ist, dass er den Puffer selbst zuweist (wenn Sie wollen) und realloc() den Puffer, den Sie übergeben, wenn er zu klein ist. (Das bedeutet, dass Sie etwas, das von malloc() erhalten wurde, weitergeben müssen).

Dies beseitigt einige der Schmerzen von fgets / fgetc, und Sie können hoffen, dass derjenige, der die C-Bibliothek geschrieben hat, die es implementiert, darauf achtete, es effizient zu machen.

Bonus: Die Manpage unter Linux hat ein schönes Beispiel dafür, wie man es effizient einsetzen kann.

    
Mat 03.03.2011 21:05
quelle
2

Wenn Ihnen die Leistung wichtig ist, möchten Sie in der Regel getc anstelle von fgetc aufrufen. Der Standard versucht, getc als Makro zu implementieren, um den Funktionsaufruf zu vermeiden.

Früher war die Hauptsache wahrscheinlich Ihre Strategie bei der Zuweisung des Puffers. Die meisten Leute verwenden feste Inkremente (z. B. wenn / wenn der Speicherplatz knapp wird, weitere 128 Bytes zuweisen). Ich rate stattdessen, einen konstanten Faktor zu verwenden. Wenn Ihnen der Speicherplatz ausgeht, weisen Sie einen Puffer zu, der etwa 1 1/2 mal so groß ist wie die vorherige Größe.

Besonders wenn getc als Makro implementiert ist, ist der Unterschied zwischen getc und fgets normalerweise sehr gering, so dass Sie sich besser auf andere Probleme konzentrieren sollten.

    
Jerry Coffin 03.03.2011 21:11
quelle
0

Wenn Sie eine maximale Zeilenlänge festlegen können, sogar eine große, dann würde ein fgets den Trick machen. Wenn nicht, sind mehrere fgets -Aufrufe immer noch schneller als mehrere fgetc -Aufrufe, da der Overhead der letzteren höher ist.

Eine bessere Antwort ist jedoch, dass es sich nicht lohnt, sich über den Leistungsunterschied Gedanken zu machen, solange und solange Sie nicht müssen. Wenn fgetc schnell genug ist, was ist es dann wichtig?

    
Thom Smith 03.03.2011 21:02
quelle
0

Ich würde einen großen Puffer zuweisen und dann fgets verwenden, überprüfen, neu zuweisen und wiederholen, wenn Sie nicht bis zum Ende der Zeile gelesen haben.

Jedes Mal, wenn Sie lesen (entweder über fgetc oder fgets), führen Sie einen Systemaufruf aus, der Zeit benötigt. Sie möchten die Häufigkeit des Auftretens minimieren. Das heißt, dass fgets weniger oft aufgerufen werden und das Iterieren im Speicher schneller ist.

Wenn Sie von einer Datei lesen, ist mmap() ing in der Datei eine andere Option.

    
Jesse Cohen 03.03.2011 21:10
quelle

Tags und Links