Andreas Korthaus: Zusatzfrage wegen Bedenken

Beitrag lesen

Hallo!

Die Dateinamen sind 55 Zeichen lang. Wieviel Speicher würde dann ein indiziertes Array bei 120.000 Einträgen benötigen?

Mmmh, da müsste man wissen wie PHP das intern verwaltet.

Einen Ansatz gibt es hier: http://marc.theaimsgroup.com/?l=php-dev&m=110259346006082&w=2

Formel: 42 * number of array elements + size of keys + data

also wenn ich das richtig verstehe müsste das etwas so aussiehen:

120000 * (42 + 55 + 1) =  ca. 12 MB

Kommt ja auch ungefähr hin mit dem was Du überschlagen hast.

Bedenken hätte ich da auch.

Es kommt drauf an. Wenn es kein Problem für den Server ist hätte ich kein Problem damit wenn das Script >100 MB verbraucht. Denn nur wenn sich die Daten als PHP-Arrays im RAM befinden geht das ganze gleichzeitig verhältnismäßig effizient und unproblematische (siehe Deine "Problematik" unten).

Evtl. kannst Du mit zeilenweisem abarbeiten von zwei Flatfiles etwas
resourcenschonenderes basteln.

Man könnte z.B. auch direkt relativ RAM-schonend mit den DB-Daten arbeiten, wenn man mysql_unbuffered_query verwendet (natürlich darf man die dann nicht in ein Array schreiben...).
Vielleicht kann man auch die lokalen Dateinamen in die DB schreiben, das heißt in eine temporäre Tabelle, evtl. HEAP. Du könntest in einer Schleife ohne viel Ram zu verbrauchen eine Datei erzeugen, die entweder direkt als "Daten" in die DB eingelesen werden kann, oder direkt ein SQL-Statement erzeugen. Dies dann möglichst effizient (vermutlich am besten über den lokalen mysql-client, bei remote-server evtl. auf komprimierte Übertragung achten!) in die DB einlesen. Dann könntest Du mit einem entsprechend effizienten SQL-Statement alle Dateinamen filtern, die zu löschen sind.

Oder Du kannst evtl. mit Datei-IDs arbeiten. Das heißt noch irgendwo eine Datei-ID führen, so dass Du die langen Namen nicht brauchst. Damit ließe sich sicherlich die Hälfte des benötigten Arbeitsspeichers sparen.

120.000 Dateien in einem Verzeichnis ist nicht unbedingt die beste Idee, vor allem wenn man kein Dateisystem verwendet, welches mit sowas effizient umgehen kann. Wenn Du einmalig die Dateinamen in eindeutige IDs (Zahlen) umbenennst, köntest Du z.B. auch direkt Verzeichnisse anlegen. Wenn Du kein Dateisystem verwendest welches effizient mit vielen Dateien im Verzeichnis umgehen kann (AFAIR z.B. ReiserFS) könntest Du z.B. alle Dateien dessen ID mit 1 anfängt (oder besser endet) in Verzeichnis 1 legen.
Die ersten Ziffern zu verwenden hat den Vorteil dass man entsprechende Einträge aus der DB indizieren und so effizient abfragen kann, wenn man die letzten Ziffern verwendet ist die Verteilung der Dateien auf die Verzeichnisse allerdings gleichmäßiger. Kommt also drauf an was man genau machen will.
So wäre zum einen der Zugriff schneller, außerdem könntest Du die Dateien beim lesen in 10 gleiche Teile teilen (z.B. per glob('*1')).
Oder wenn Du noch "tiefer" gehst die ersten oder letzten _zwei_ Ziffern verwenden, wären dann 100 gleiche Teile usw. Aber dann müsstest Du vermutlich einiges umbauen.

Ich würde allerdings nicht zu viel Zeit in eine Optimierung bzgl. RAM-Verbrauch stecken, falls es hier in absehbarer Zeit eh keine Probleme geben wird.
Das Schwierigkeit liegt darin, dass Du - damit das ganze schnell ist - mindestens eines der beiden Listings als PHP-Array im RAM haben solltest. Wenn Du das vermeiden willst/musst wird es halt mit Sicherheit _deutlich_ langsamer und komplizierter.

Mit Hilfe des Profilers von xdebug kannst Du sehr gut untersuchen wo genau im Script Zeit/RAM verbraucht wird.

Damit würde ich einfach ein paar Ideen ausprobieren.

Grüße
Anreas

--
SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/