Bessere Performance bei einer großen oder mehreren kleinen Dateien?

Paula

Erfahrenes Mitglied
Hallo zusammen,

ich soll Daten in eine Datenbank schreiben. Diese Daten erhalte ich regelmäßig als Textdatei. Ich frage mich nun was besser für die Performance ist:
Eine große Datei mit Trennzeichen oder mehrere kleinere Dateien wo jede Datei als Trenner dient?

Derzeit läuft meine Bearbeitung im Skript wie folgt ab:
PHP:
$file = file('foo.txt');
foreach ($file as $line) {
     ... // Details
}
Ist dies so am sinnvollsten oder gibt es bessere Methoden?

Insgesamt bekomme ich mehrere Datensätze, die Dateien sind von 500KB bis 20MB groß.


Gruß
 
Eine einzige große Datei kann sicherlich schneller verarbeitet werden als viele kleine. Denn dabei entfällt das für jede Datei nötige Lokalisieren, Öffnen und Schließen der Datei. Wenn du zudem wie in deinem Beispiel nur mit dem Dateizeiger arbeitest anstatt den gesamten Inhalt auf einmal auszulesen, sollte es auch keine Speicherprobleme geben.
 
Wenn du zudem wie in deinem Beispiel nur mit dem Dateizeiger arbeitest anstatt den gesamten Inhalt auf einmal auszulesen, sollte es auch keine Speicherprobleme geben.
Das Problem habe ich jedoch schon! Wenn ich z.B. die 25MB Datei nehmen, so erhalte ich die Meldung:
Code:
Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 24652268 bytes) in ...
Gibt es eine Möglichkeit, dass ich das Problem umgehen kann - ohne die php.ini zu verändern?

Bzw. wie meinst du es genau mit deinem Satz? Schlussendlich möchte ich nur jede Zeile einzeln auslesen.
 
Dann gibst du vermutlich die Ressourcen nicht wieder frei sondern sammelst beispielsweise die Inhalte in Variablen, die eigentlich nicht mehr benötigt werden.
 
Ich habe mal zum testen folgendes probiert:
PHP:
$filename = 'foo.dat';
$file = file($filename);
echo $filename;
Bei diesen drei Zeilen erhalte ich auch obige Fehlermeldung. Also an unnötigen Daten kann es nicht liegen, sondern wohl doch an der php.ini?
Oder habe ich doch irgendwie einen Gedankenfehler?

// edit
PHP:
$file = readfile($filename);
So klappt die Ausgabe bei meinem Test. Ich teste mal weiter.
 
Zuletzt bearbeitet:
Wie groß ist den foo.dat?

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 24652268 bytes) in ...

Ist jawohl ne klare Aussage...

MfG Tabakhase
 
Ich beziehe mich auch auf folgenden Satz:
Wenn du zudem wie in deinem Beispiel nur mit dem Dateizeiger arbeitest anstatt den gesamten Inhalt auf einmal auszulesen, sollte es auch keine Speicherprobleme geben.
Ich möchte gerne verstehen was er meint und es dann auch umsetzen. :)


// edit

Folgendes klappt bei einer großen Datei:
PHP:
$handle = fopen($filename, 'r');
while (!feof($handle)) {
    $line = fgets($handle, 4096);
    // krams
}
fclose($handle);
 
Zuletzt bearbeitet:
Der „Fehler“ bei deinen file()-Beispiel ist, dass du den gesamten Inhalt der Datei in einer Variable speichert. Damit ist der verfügbare Arbeitsspeicher natürlich schnell erschöpft.
Wenn du den Inhalt sowieso nicht weiterverarbeiten möchtest, sollte du ihn direkt mit der readfile()-Funktion ausgeben. Andernfalls solltest du die fopen()-Funktion nutzen und die Datei sukzessiv, also logischen Abschnitt für logischen Abschnitt (in den meisten Fällen zeilenweise), auslesen und verarbeiten. Das kann den für die Verarbeitung benötigten Arbeitsspeicher drastisch verringern, da immer nur der aktuell zu verarbeitende Abschnitt ausgelesen wird.
 
Zurück