PyDiskEraser - Miserable Prefomance ?!?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 3. März 2005, 09:06

Ich hab nun ein paar statistische Ausgaben in den PyDiskEraser eingebaut... Demnach ist die Preformance recht miserabel... Ich hab immer so um die 20MB/s... Das ist eigentlich recht wenig...

Ist die Preformance wirklich so mies, oder hab ich da einen Fehler in der Berechnung gemacht? Kann es bitte mal einer nachprüfen?
v0.0.5 Source Download
v0.0.5 Source ansehen

Die aktuelle Version unter: http://www.jensdiemer.de/Programmieren/PyDiskEraser/

Ursprungs Thread: http://python.sandtner.org/viewtopic.php?t=2803
Zuletzt geändert von jens am Donnerstag 3. März 2005, 11:33, insgesamt 1-mal geändert.
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Donnerstag 3. März 2005, 10:14

Hab Linux. Sorry. Wie schnell ist Deine HD?

cu beyond
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 3. März 2005, 11:00

Generell sollte es auch unter Linux funktionieren, wenn man getFreeSpace() auch zu Linux kompatibel macht, Anregungen unter: http://python.sandtner.org/viewtopic.php?p=16375#16375

Also normalerweise sollten meine Platten ca. 40-45MB/s schreibend schaffen...

Nun ist PyDiskEraser nach 85Min mit dem Löschen einer 60GB (54802MB) Platte fertig... Die Durchschnittliche Datenrate lag gerade mal bei 10.7MB/s... Gut die Platte hab ich jetzt über FireWire 400 angeschlossen... Theoretisch sollte damit aber 20-25MB/s möglich sein... Angefangen hat er auch so bei 20MB/s zum Ende hin sank die Rate allerdings auf schlappe 9-9.5MB/s ein...

Wenn ich es mal auf meine lokalen SATA Platte versuche, dann ist die Rate noch viel niedriger... So bei ca.13MB/s! Zwar ist die Platte nicht gerade leer und bestimmt etwas fragmentiert, aber das ist auf jeden Fall viel zu niedrig! (Ich teste es mal mit den Hitachi Tools)

Vielleicht ist es keine gute Idee alles in einer Datei zu schreiben... Vielleicht solle ich es in kleinere Brocken aufteilen?!?
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 3. März 2005, 15:36

Leider spucken die "Hitachi Tools" nirgendwo die Preformance der Platten aus ;( Schade...

Kann es evtl. noch jemand Testen?

Die aktuelle Version sollte nun auch unter Linux mit MountPoints funktionieren... Zum test muß es auch nicht wirklich die ganze Platte voll schreiben lassen... Einfach irgendwann abbrechen, in der neuen Version wird auch das abgefanngen und die Eraser-Datei gelöscht um den Speicherplatz wieder frei zu geben:

Download v0.0.6
Sourcen ansehen v0.0.6
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Donnerstag 3. März 2005, 20:05

Ich habe gesehen, daß Du jedesmal tatsächlich Random-Daten erstellst. Das könnte Zeit kosten. Probier mal die Datenrate aus, wenn Du nur Random-Daten erstellst.

cu beyond
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 3. März 2005, 20:33

Warum?

Code: Alles auswählen

    for i in xrange( BlocksToWrite ):
        [...]

        if WritesRandomTrash:
            # Schreibt einen Block zufälliger Zeichen
            FileHandle.write( os.urandom(BlockSize) )
        else:
            # Schreibt einen Block NULL-Bytes
            FileHandle.write( NullBytesBlock )
Random-Daten werden nur erzeugt, wenn es mit "-r" angegeben wurde (WritesRandomTrash = True) ansonten werden NULL-Bytes geschrieben und das immer per Default 10MB auf einmal... Somit dürfte generell die Preformance der for-Schleife nicht so sehr ins Gewicht fallen, weil sie vergleichsweise wenig Durchlauf hat...
BlackJack

Freitag 4. März 2005, 01:41

Der Quelltext wird ja auf Deiner Homepage superklein dargestellt. Das Problem mit dem CSS, was Du an anderer Stelle erwähntest, nehme ich an!?

Das löst jetzt erstmal nicht Dein Laufzeitproblem, aber die Datei würde ich mit 'os.tmpfile()' anlegen. Dann brauchst Du Dich nicht um das Löschen zu kümmern -- die Datei hat keinen Eintrag in irgendeinem Verzeichnis und wird vom Betriebssystem automatisch gelöscht wenn sie geschlossen wird. Also spätestens wenn Dein Programm, aus welchem Grund auch immer, beendet wird.
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Freitag 4. März 2005, 02:00

Dachte es wäre beim Randomschreiben. Wenn's generell so ist, dann ist eben Dein PC betrifft mit einem derartigen Dateninput nicht schneller.

cu beyond
BlackJack

Freitag 4. März 2005, 23:39

Okay ich hab's mal getestet. Erstmal musste ich es unter Linux zum laufen bekommen. Dabei ist mir folgendes am Quelltext aufgefallen (Vorsicht: lang und unfreundlich :wink: )

Am Anfang fehlt die Unix-#!-Zeile damit das Betriebssystem auch weiss, welcher Interpreter für diese Datei gestartet werden soll:

Code: Alles auswählen

#!/usr/bin/env python
Einige Zeilen sind länger als 80 Zeichen. Das betrifft zum Beispiel Docstrings. Die werden per Konvention als mehrzeilige Zeichenketten mit ``"""`` angelegt.

Du verletzt die Namenskonventionen mit fast allen Variablen. Grosse Anfangsbuchstaben kennzeichnen in vielen Programmiersprachen Klassen und nicht Inkarnationen von Klassen. Der Python Style-Guide geht sogar so weit, in Funktionsnamen nur Kleinbuchstaben zu verwenden.

Was beim Importieren eines Moduls ausgeführt wird, sollte sich auf das minimal Notwendige beschränken. Bei Dir läuft der komplette Code dabei ab. Das hat mehrere Nachteile. Zum einen kann man das Modul nicht im Pythoninterpreter importieren und die Funktionen einzeln ausprobieren. Zum anderen hast Du auf diese Weise viele globale Variablen, was die Gefahr der Abhängigkeiten von Funktionen erhöht. Bei `DeactivateNTFScompression` verwendest Du zum Beispiel den Parameter `File` gar nicht und benutzt stattdessen das globale `EraserFile`. Das ist ein Fehler der Dir aufgefallen wäre, wenn `EraserFile` nicht global sondern nur in einer `main()` Funktion existieren würde.

`EraserFile` ist nicht portabel weil ein '\' hart kodiert ist, der unter Linux/Unix besser ein '/' sein sollte. Am einfachsten ist es, wenn man für Operationen mit Pfadnamen die Funktionen aus `os.path` benutzt:

Code: Alles auswählen

EraserFile = os.path.join(Drive, 'DiskEraser.dat')
In `getFreeSpace` wird eine Zeichenkette als Ausnahme benutzt, das ist "deprecated". Ausserdem schlägt diese Ausnahme bis zum Benutzer durch und der bekommt einen Traceback präsentiert. Und die Ausnahme tritt bei mir wirklich auf, weil es 'posix' bei `sys.platform` wohl nicht gibt. Bei mir steht dort 'linux2'. Du solltest besser `os.name` verwenden und auf 'nt' bzw. 'posix' testen. Da kann man sicher sein, das nur die in der Dokumentation erwähnten Namen auftreten können: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'.

Das Modul `statvfs` benötigt man nicht mehr -- die Informationen sind auch als Attribute des Rückgabewertes von `os.statvfs()` abfragbar, also:

Code: Alles auswählen

stats = os.statvfs('/')
return stats.f_bavail * stats.f_bsize
Du testest, ob der Laufwerksname zwei Zeichen lang ist und das zweite Zeichen ein ':' ist. Damit funktioniert das Programm nicht unter Unix. Laufwerksnamen gibt es dort nicht und ein Mountpoint kann so ziemlich überall in der Verzeichnishierarchie eingehängt sein.

Zur Ausgabe von Fehlern kann man die `error()` Methode vom optparse-Parser benutzen. Dann wird die Fehlermeldung nach der kurzen Benutzungsinformation ausgegeben.

Dateien zu öffnen und sie nicht wieder zu schliessen ist schlechter Stil. Dazu zählen auch Dateien, die von einem Aufruf von `os.popen()` zurückgegeben werden.

Das deaktivieren der NTFS-Komprimierung gibt unter Linux natürlich einen Fehler aus.

Im Englischen gibt es übrigens nur recht selten zusammengesetzte Worte mit einem Bindestrich und es wird mehr klein geschrieben. Also "random bytes" statt "Random-Bytes" und "blocksize" statt "Block-Size".

Zum Schluss der Test:

Code: Alles auswählen

python PyDiskEraser_v006,5.py /old.data/

# versus

dd_rescue -b 10M -m 1G /dev/zero /old.data/test.dat
Ist bei mir gleich schnell. Am Anfang wird viel/schnell geschrieben -- in den Cache vom Betriebssystem und der Festplatte, danach werden beide Programme gleichermassen "langsam". Die durchschnittliche Geschwindigkeit ist nahezu gleich.
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 7. März 2005, 09:04

Ich danke dir erstmal für deine Hilfestellung. Mein Code ist wohl nicht das beste Beispiel für ein anständiges Python-Programm :) Aber ich habs auch recht schnell runter geschrieben und ich wollte es in ersterlinie für Windows haben...

Einige deiner Vorschläge hab ich umgesetzt... Jedoch wüßte ich ger mehr über die error() Möglichkeit beim Opt-Parser... Darüber konnte ich nicht's finden :(
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 7. März 2005, 17:40

jens hat geschrieben:Einige deiner Vorschläge hab ich umgesetzt... Jedoch wüßte ich ger mehr über die error() Möglichkeit beim Opt-Parser... Darüber konnte ich nicht's finden :(
Wie wäre es damit? Ist jetzt auch nicht soo sehr umfassend..
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten