Ich habe mich gefragt, ob jemand dieses Problem beleuchten könnte. PHP 5.3.0:)
Ich habe eine Schleife, die den Inhalt einer CSV-Datei (groß, 200 MB) ergreift, die Daten verarbeitet, einen Stapel von Variablen für mysql-Einfügungen erstellt und sobald die Schleife fertig ist und die Variablen erstellt habe, füge ich ein die Information.
Nun, zum einen funktioniert das mysql-Insert perfekt, es gibt keine Verzögerungen und alles ist gut, aber es ist die LOOP selbst, die die Verzögerung hat. Ich habe ursprünglich fgetcsv () verwendet, um die CSV-Datei zu lesen, aber im Vergleich zu file_get_contents () eine ernsthafte Verzögerung - so wechselte ich zu file_get_contents (). Die Schleife wird in wenigen Sekunden ausgeführt, bis ich versuche, eine Funktion hinzuzufügen (ich habe auch den Ausdruck innerhalb der Schleife ohne die Funktion hinzugefügt, um zu sehen, ob es hilft), um ein Array mit den CSV-Daten aus jeder Zeile zu erstellen ist das, was zu ernsthaften Verzögerungen bei der Parsing-Zeit führt! (Der Unterschied ist etwa 30 Sekunden basierend auf dieser 200 MB-Datei, aber abhängig von der Dateigröße der CSV-Datei, die ich denke)
Hier ist ein Code, damit Sie sehen können, was ich mache:
%Vor%Das Ausführen der obigen Schleife wird fast sofort ohne die Zeile ausgeführt:
%Vor%Ich habe auch versucht, eine Funktion wie folgt (außerhalb der Schleife) zu erstellen:
%Vor%und Aufruf der Funktion anstelle des einen Liners:
%Vor%Mit wieder keinem Glück: (
Hier ist jede Hilfe hilfreich. Ich nehme an, dass die Funktion fgetcsv auf der Basis der Verzögerung, die sie verursacht, durchläuft und ein Array aus der Datenzeile erstellt.
Danny
Die Regex-Teilausdrücke (begrenzt durch "(...)") sind das Problem. Es ist trivial zu zeigen, dass das Hinzufügen dieser Elemente zu einem Ausdruck die Leistung erheblich reduzieren kann. Das erste, was ich versuchen würde, ist mit preg_replace () aufhören, einfach zu entfernen führende und nachfolgende doppelte Anführungszeichen (trim () wäre eine bessere Wette dafür) und sehen, wie viel das hilft. Danach müssen Sie möglicherweise eine nicht regex-Methode versuchen, die Zeile zu analysieren.
Ich habe teilweise eine Lösung gefunden, ich sende einen Stapel, um nur 1000 Zeilen gleichzeitig zu durchlaufen (php läuft um 1000, bis es das Ende der Datei erreicht).
Ich setze dann nur:
%Vor%in den 1000 Zeilen, so dass es nicht für die WHOLE-Datei gesetzt ist, die Probleme verursachte.
Es schleift jetzt und fügt in 1-2 Sekunden 1000 Zeilen in die mysql-Datenbank ein, womit ich zufrieden bin. Ich habe das Skript so eingerichtet, dass es 1000 Zeilen wiederholt, sich an seinen letzten Ort erinnert und dann zu den nächsten 1000 Schleifen zurückkehrt, bis es das Ende erreicht hat. Es scheint, als würde es funktionieren!
Ich würde sagen, der Hauptschuldige ist die Komplexität von preg_split () regexp. Und die explode () isst wahrscheinlich einige Sekunden.
%Vor%könnte ersetzt werden durch:
%Vor%Aber, ich stimme dem obigen Vorschlag von ITroubs zu, wäre fgetcsv () wahrscheinlich eine viel bessere Lösung.
Ich würde vorschlagen, fgetcsv zum Parsen der Daten zu verwenden. Es scheint, als ob die Erinnerung die größte Wirkung hat. Um also 200 MB RAM zu vermeiden, sollten Sie Zeile für Zeile wie folgt analysieren:
%Vor% Alternativ: Die Verwendung von Bedingungen in Preg ist in der Regel sehr teuer. Es kann manchmal schneller sein, diese Zeilen mit explode()
und trim()
mit dem Parameter $charlist
zu verarbeiten.
Die andere Alternative, wenn Sie immer noch preg verwenden möchten, fügen Sie den S-Modifikator hinzu, um den Ausdruck zu beschleunigen.
Ссылка
S < br> Wenn ein Muster mehrere Male verwendet wird, lohnt es sich, mehr Zeit mit der Analyse zu verbringen, um die Zeit für den Abgleich zu verkürzen. Wenn dieser Modifikator gesetzt ist, wird diese zusätzliche Analyse durchgeführt. Momentan ist das Studium eines Musters nur für nicht verankerte Muster nützlich, die keinen festen Startzeichen haben.
Tags und Links php loops performance