Hallo Forum,
ich habe ein Python-Script erstellt welches eine große Anzahl an Ordnern mit vielen Dateien als Inhalt löscht.
Zuerst habe ich dies mit shutil.rmtree(folder) probiert, bin dann aber daran hängen geblieben, dass dies doch sehr lange dauert, da ein Ordner nach dem nächsten gelöscht wird.
Ich bin dann hergegangen und habe das Script so beschleunigt:
mydelcmd = "rm -r " + mydelfol
subprocess.Popen(mydelcmd, shell=True)
Nun werden alle Folder parallel (mehr oder weniger) gelöscht. Ich persönlich finde aber die erste Methode mit shutil schöner. Kann man dies auch parallelisieren?? Ein Tip in die richtige Richtung reicht mir schon
Grüße und Danke
Jochen
Paralelisieren von shutil.rmtree
- veers
- User
- Beiträge: 1219
- Registriert: Mittwoch 28. Februar 2007, 20:01
- Wohnort: Zürich (CH)
- Kontaktdaten:
Ich weiss ja nicht was für eine Implementierung von rm du verwendest, aber die vom GNU Projekt arbeitet nicht parallel.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Hallo,
ist vielleicht ein bischen doof ausgedrückt von mir.
Natürlich arbeitet der rm nicht parallel, aber dadurch dass ich das für jeden Ordner absetze und nicht warten muss, bis der Thread zurückkommt, ist das "quasi parallel".
Wenn ich das mit shutil.rmtree mache, wartet mein Script bei jedem Ordner bis der rm-Thread aus dem Kern zurück kommt.
Ich suche nun eine Möglichkeit das zu optimieren
Grüße
Jochen
ist vielleicht ein bischen doof ausgedrückt von mir.
Natürlich arbeitet der rm nicht parallel, aber dadurch dass ich das für jeden Ordner absetze und nicht warten muss, bis der Thread zurückkommt, ist das "quasi parallel".
Wenn ich das mit shutil.rmtree mache, wartet mein Script bei jedem Ordner bis der rm-Thread aus dem Kern zurück kommt.
Ich suche nun eine Möglichkeit das zu optimieren
Grüße
Jochen
Everything was all good just a week ago...
Hoi,
verstehe nicht ganz wozu das gut sein soll und so sind dies wirklich nur eine neugierige Fragen und keine besserwisserischen Bemerkungen:
Ist dieses quasiparallele Löschen wirklich schneller? Bei einer Platte gibt es nur einen Lese-/Schreibkopf, nicht wahr? Und bei einem Festplatten-Verbund, sollte das im Zusammenspiel mit Controller und OS doch auch keinen Unterschied machen, oder? Wenn doch, wo kommt der Unterschied her?
Gruß,
Christian
verstehe nicht ganz wozu das gut sein soll und so sind dies wirklich nur eine neugierige Fragen und keine besserwisserischen Bemerkungen:
Ist dieses quasiparallele Löschen wirklich schneller? Bei einer Platte gibt es nur einen Lese-/Schreibkopf, nicht wahr? Und bei einem Festplatten-Verbund, sollte das im Zusammenspiel mit Controller und OS doch auch keinen Unterschied machen, oder? Wenn doch, wo kommt der Unterschied her?
Gruß,
Christian
Hi,
naja irgendwo hast du Recht. Bei mir ist es gefühlt schon etwas schneller. Da die rm-Threads asynchron in den Kern abgesetzt werden, kann ich die Zeit aber auch nicht mit einem time messen. Ich schau halt ins FS, wie lange es dauert bis alle Ordner weg sind.
Das Script läuft halt schneller durch, da das löschen der Ordner dann im Hintergrund läuft.
Ich lass es erstmal so wie es ist....aber noch eine Frage zum Verständnis,
shutil.rmtree macht doch auch nichts anderes, als das Shell "rm -r" aufzurufen, oder??
Grüße und Danke
Jochen
naja irgendwo hast du Recht. Bei mir ist es gefühlt schon etwas schneller. Da die rm-Threads asynchron in den Kern abgesetzt werden, kann ich die Zeit aber auch nicht mit einem time messen. Ich schau halt ins FS, wie lange es dauert bis alle Ordner weg sind.
Das Script läuft halt schneller durch, da das löschen der Ordner dann im Hintergrund läuft.
Ich lass es erstmal so wie es ist....aber noch eine Frage zum Verständnis,
shutil.rmtree macht doch auch nichts anderes, als das Shell "rm -r" aufzurufen, oder??
Grüße und Danke
Jochen
Everything was all good just a week ago...
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Jochen!Amberfox hat geschrieben:shutil.rmtree macht doch auch nichts anderes, als das Shell "rm -r" aufzurufen, oder?
Nein, das macht es nicht. shutil.rmtree läuft jede Datei und jeden Unterordner rekursiv durch. Prüft jede Datei ob diese ein Ordner ist und übergibt je nach Art der Datei an ``os.remove`` oder ``os.rmdir``. Eine ziemliche Schleifenarbeit. So etwas ist direkt in C garantiert schneller.
Also der Aufwand von "rm" aus "coreutils" ftp://ftp.gnu.org/gnu/coreutils/ ist schon recht enorm. Du musst dir mindestens "rm.c" und "remove.c" ansehen umd einen Eindruck zu bekommen. Dass "rm" wirklich viel schneller ist, wundert mich nicht. In so einem Fall ist die perfekte Optimierung: per subprocess "rm" aufrufen.
Die Lösung, per subprocess auf so ein spezialisiertes Programm zurück zu greifen ist oft keine schlechte Lösung. Ich verstehe nicht, was dir daran nicht gefällt.
Allerdings würde ich die Argumente als Liste an subprocess übergeben. Dann kümmert sich subprocess um das korrekte Quoting.
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hoi,
hab gerade die Quellen durchblättert:
Gruß,
Christian
hab gerade die Quellen durchblättert:
Ich weiß nicht,ob das einen sichtbaren Unterschied macht. Letztlich wird (bei Linux, aber davon gehe ich bei diesem Post mal aus) auf posix zurückgegriffen und alles weitere ist in C. Vermutung: Es braucht schon sehr viele Ordner (nicht sonstige Dateien), damit man hier einen Unterschied merkt - oder sieht das jemand anders?gerold hat geschrieben: Eine ziemliche Schleifenarbeit. So etwas ist direkt in C garantiert schneller.
Gruß,
Christian
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Windows hat kein `rm`. Damit bringst du also platformabhängigkeit rein, wo es eigentlich keine bräuchte. Dann musst du testen ob es Windows ist und dort dann `del` aufrufen und somit für jede Platform gucken wie das Löschkommando dort ist.gerold hat geschrieben:Die Lösung, per subprocess auf so ein spezialisiertes Programm zurück zu greifen ist oft keine schlechte Lösung. Ich verstehe nicht, was dir daran nicht gefällt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Leonidas!Leonidas hat geschrieben:Windows hat kein `rm`. Damit bringst du also platformabhängigkeit rein, wo es eigentlich keine bräuchte. Dann musst du testen ob es Windows ist und dort dann `del` aufrufen und somit für jede Platform gucken wie das Löschkommando dort ist.
Ist das ein Problem?
Code: Alles auswählen
>>> import sys
>>> if sys.platform.startswith("win"):
... print "Windows"
... else:
... print "Linux und Co"
...
Windows
>>>
So etwas würde man natürlich nicht oder nur gut getestet für ein Python-Erweiterungsmodul verwenden. Aber sicher doch um schnell und einfach ein spezielles Problem zu lösen. Die ganze Linux-/Unix-Shellprogrammierung baut darauf auf, kleine Dienstprogramme gezielt einzusetzen. Und das funktioniert immer noch sehr gut.
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Klar, das geht schon. Aber weißt du wie der Befehl fürs Löschen unter Plan 9, Inferno, und $IRGENDEIN_EXOTISCHES_OS_AUF_DEM_PYTHON_LÄUFT ist? Du kannst ja für die bekannten Platformen so etwas anbieten, aber generell würde ich das als "Unschön" bezeichnen. Du nutzt ja sicher auch Pythons Stdlib, obwohl man unter Windows einige Sachen auch über `ctypes` und die MSVCRT lösen kann.gerold hat geschrieben:Ist das ein Problem?(man könnte je nach Bedarf und Einsatzzweck noch weitere Plattformen in die Auswahl mit einbeziehen)Code: Alles auswählen
>>> import sys >>> if sys.platform.startswith("win"): ... print "Windows" ... else: ... print "Linux und Co" ... Windows >>>
Der Code ist optimalerweise für alle Plattformen gleich. Das `shutil.rmtree` nicht sonderlich schnell ist mag ja sein, aber da wäre es besser dem Interpreter eine Implementation zu geben, die besser ist. Davon profitieren alle. Klar, das klingt nun etwas arg "abgehoben" und die Lösung Subprozesse zu starten um Dinge zu erledigen geht ja auch, aber meines Ermessens ist sie einfach nicht schön.
Das dachten sich auch die Entwickler von Git. Das ist schnell und eine Mischung aus C, Perl und bash die unter Windows nicht richtig lauffähig ist. Daran ist nicht nur der C-Teil schuld.gerold hat geschrieben:Aber sicher doch um schnell und einfach ein spezielles Problem zu lösen. Die ganze Linux-/Unix-Shellprogrammierung baut darauf auf, kleine Dienstprogramme gezielt einzusetzen. Und das funktioniert immer noch sehr gut.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Das wäre ein Problem falls es sich wirklich nur um "gefühlte" Geschwindigkeit handelt. Also ich würde messen wieviel es bringt bevor ich mir eine eventuell unnötige Platformabhängigkeit einbaue.
Hallo,
vielen Dank für die Denkanstöße!!
Also ich denke ich lasse es dann erstmal so. Die angesprochenen rm.c und remove.c schaue ich mit interesse halber einfach mal an.
Die Platformunabhängigkeit ist in meinem Fall erstmal nicht ganz so wichtig, daher nutze ich das Aufrufen des "rm", um einfach die gefühlte Geschwindigkeit zu haben. Ich schau mal ob ichs doch schaffe die Zeit zu stoppen und melde mich dann, wenn ich wirklich Testergebnisse habe, was schneller geht.
Viele Grüße in die Runde
Jochen
vielen Dank für die Denkanstöße!!
Also ich denke ich lasse es dann erstmal so. Die angesprochenen rm.c und remove.c schaue ich mit interesse halber einfach mal an.
Die Platformunabhängigkeit ist in meinem Fall erstmal nicht ganz so wichtig, daher nutze ich das Aufrufen des "rm", um einfach die gefühlte Geschwindigkeit zu haben. Ich schau mal ob ichs doch schaffe die Zeit zu stoppen und melde mich dann, wenn ich wirklich Testergebnisse habe, was schneller geht.
Viele Grüße in die Runde
Jochen
Everything was all good just a week ago...