Lesen einer Datei schneller in C
Hmm ich Frage mich, ob es sich um einen Weg, um eine DATEI Lesen schneller als die Verwendung von fscanf()
Zum Beispiel nehmen wir an, dass ich diesen text
4
55 k
52 o
24 l
523 i
Zuerst möchte ich Lesen, die erste Zahl gibt, die uns die Anzahl der folgenden Zeilen.
Lassen Sie diese Nummer aufgerufen werden N.
Nach N, ich will Lesen N Zeilen, die eine ganze Zahl und ein Zeichen.
Mit fscanf
wie es sein würde, diese
fscanf(fin,"%d %c",&a,&c);
- Hast du profiler Ihnen sagen, dass
fscanf
ist die Quelle Ihrer performance-problem? - Das klingt ein wenig wie Hausaufgaben.
- Frage zu Parsen einer Datei schneller, anstatt zu Lesen.
- Im Grunde möchte ich es zu benutzen in der Praxis Wettbewerben.
- Haben Sie versuchen, Messen Sie die Lesegeschwindigkeit Ihrer Programm in MB/s? Vielleicht ist es in der Nähe deiner hdd maximale lese-Geschwindigkeit. Sie müssen auf jeden Fall Vermessen und Profilieren.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie fast nicht verarbeiten, so wohl der Flaschenhals ist die Datei-system-Durchsatz. Allerdings sollten Sie Messen zuerst, ob es wirklich ist. Wenn Sie nicht wollen, um einen profiler verwenden, können Sie einfach Messen Sie die Laufzeit Ihrer Anwendung. Die Größe von input-file dividiert durch die Laufzeit kann verwendet werden, um zu überprüfen, ob Sie erreicht haben, die Datei system Durchsatz zu begrenzen.
Dann, wenn Sie weit Weg von der oben genannten Grenze, die Sie wahrscheinlich benötigen, um die Art und Weise optimieren Sie die Datei Lesen. Es kann besser sein, es zu Lesen in größeren Blöcken mit
fread()
und dann den Puffer im Speicher abgelegt, mitsscanf()
.Können Sie auch analysieren, die Puffer selbst, die wäre schneller als
*scanf()
.[Bearbeiten]
Besonders für Drakoscha:
Also die optimierte version macht ~127MB/s, was kann mein Datei-system-Engpass oder vielleicht OS speichert die Datei im RAM. Die ursprüngliche version ist ~20 MB/s.
Getestet mit einer 80 MB Datei:
main1.c
main2.c
fgetc()
müssten an leas einem system-Aufruf. Aber wenn Siefread()
Sie Lesen, eine große portion in einem system nennen. Es ist viel schneller. Meine parsing-Algorithmus ist auf jeden Fall sehr schnell.Ist es unwahrscheinlich, dass können Sie wesentlich zur Beschleunigung des tatsächlichen Lesen der Daten. Die meisten der Zeit, die hier verbracht werden, auf die übertragung der Daten von der Festplatte in den Speicher, was unvermeidbar ist.
Bekommen Sie vielleicht ein wenig beschleunigen, durch den Austausch der
fscanf
Anruf mitfgets
und dann manuell Parsen der Zeichenfolge (mitstrtol
) zu umgehen, um den format-string Parsen, dassfscanf
zu tun hat, aber erwarten Sie keine große ersparnis.In der end, es ist in der Regel nicht Wert es zu stark optimieren I/O-Operationen, weil Sie in der Regel dominiert durch die Zeit, die es braucht, um die übertragung der eigentlichen Daten zu/von der hardware/Peripherie.
Wie üblich, beginnen Sie mit profiling zu machen, dass dieses Teil ist in der Tat ein Engpass. Tatsächlich, Dateisystem-cache sollte der kleine liest, dass Sie tun nicht sehr teuer, aber beim Lesen größerer Teile der Datei in den Speicher und dann den Betrieb auf den Speicher vielleicht (ein wenig) schneller.
Im Fall (was ich glaube, ist extrem unwahrscheinlich) ist, dass Sie brauchen, um zu sparen jedes CPU-Zyklus, den Sie schreiben, Ihre eigenen fscanf Variante, da Sie wissen, das format der Zeichenfolge und Sie müssen nur die Unterstützung von nur einer Variante. Aber diese Verbesserung würde bringen niedrige Gewinne, aber insbesondere auch auf modernen CPUs.
Den Eingang sieht aus wie in verschiedenen Programmier-Wettbewerbe. In diesem Fall optimiert der Algorithmus, nicht das Lesen.
fgets() oder fgetc() sind schneller, da Sie nicht brauchen, um ziehen Sie die gesamte Formatierung/variable Argumentliste Ballett von fscanf() in das Programm. Entweder eine der zwei Funktionen, die verlassen werden Sie mit einem manuellen Zeichen(s)-zu-Ganzzahl-Konvertierung jedoch. Noch, das Programm als ganzes viel schneller.
Nicht viel Hoffnung zu Lesen Datei schneller, da es ein system Anruf. Aber es gibt viele Möglichkeiten, um zu analysieren, ist es schneller als scanf mit spezialisierten code.
fscanf(f, "%c", &c);
anstatt das zu tunread(fd, buf, n)
oderfread(p, 1, n, f);
wenn für nur Lesen ist nicht verfügbar. Aber ich würde Wetten, dass fread wurde auch auf die Systeme, die Sie gesprochen hatten.Kasse
read
undfread
. Als Sie die Praxis für Programmier-Wettbewerbe, können Sie Sie ignorieren alle Warnungen über disk IO buttle Hals, dazu führen, dass Dateien können in Speicher oder Rohre aus anderen Prozessen Generierung von tests ("on-the-fly".Setzen Sie Ihre tests in
/dev/shm
(neue Lösung für tmpfs) oder machen Sie test-generator und pipe.Hab ich das auf die Programmierung Wettbewerbe, Analyse von zahlen in einer Weise zu
atoi
geben kann, viel Leistungssteigerung gegenüber scanf/fscanf (atoi
werden könnten, nicht vorhanden sind, so vorbereitet werden, um ihn vom hand - es ist einfach).