Performance: hash, md5, sha, hmac...

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 28. Juni 2007, 08:36

Ich wollte mal wissen, wie schnell die verschiedenen Hash Funktionen in Python v2.4 sind.
hmac kann man eigentlich ganz vergessen. Der ist so langsam das es keinen Sinn macht, diesen mit zu testen. Ansonsten dauert es ewig oder man muß die loop Anzahl so niedrig einstellen, das die anderen Tests keinen Sinn machen. Probiert es mal selber:

Code: Alles auswählen

import timeit, os, string

loop = 500000

TEST_STRING = string.ascii_letters + string.digits

tests = (
    ("hash('%s')" % TEST_STRING, ""),
    ("md5.new('%s').hexdigest()" % TEST_STRING, "import md5"),
    ("sha.new('%s').hexdigest()" % TEST_STRING, "import sha"),
    #~ ("hmac.new('%s').hexdigest()" % TEST_STRING, "import hmac"),
)

for no, test in enumerate(tests):
    print "%s - %s" % (no+1, test[0])

    test = timeit.Timer(test[0], test[1])
    print "%.2f" % test.timeit(number=loop)

    print
Ergebnis:
1 - hash('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
Test: 0.09

2 - md5.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
Test: 0.83

3 - sha.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
Test: 0.99
Die Python hash() Funktion ist also ungeschlagen. Leider dürften damit aber recht schnell Kollisionen auftreten ;(

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Donnerstag 28. Juni 2007, 16:57

Es scheint du hast nicht ganz verstanden was ein hmac ist,
Sieh dir mal das an:
http://de.wikipedia.org/wiki/HMAC

Und zu Python Hash Funktion, ich nehme mal stark an das diese nicht entwickelt wurde um Kryptographisch brauchbar zu sein.
BlackJack

Donnerstag 28. Juni 2007, 18:31

@jens: Der erste Test misst nicht Berechnung des Zeichenketten-Hashwertes, sondern nur wie schnell eine Methode aufgerufen werden kann, die eine Konstante zurück gibt. `hash()` ruft `str.__hash__()` auf und da Zeichenketten immutabel sind, wird deren Hashwert *einmal* beim erzeugen der Zeichenkette, hier also beim kompilieren, berechnet.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 28. Juni 2007, 19:24

@veers: Ehrlich gesagt, hab ich mir wirklich nicht hmac angesehen :oops:

@BlackJack: Hm. Dann müsste ich den Test-String dynamisch erzeugen... Ob es reicht ein eval() zu machen ? Naja... Egal...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 29. Oktober 2007, 19:10

Du kannst ja noch ``binascii.crc32`` benchmarken, für einige Anwenungsfälle ist das auch brauchbar.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 30. Oktober 2007, 08:46

ok, hier:

Code: Alles auswählen

import timeit, os, string

loop = 700000

TEST_STRING = string.ascii_letters + string.digits

tests = (
    ("md5.new('%s').hexdigest()" % TEST_STRING, "import md5"),
    ("sha.new('%s').hexdigest()" % TEST_STRING, "import sha"),
    ("binascii.crc32('%s')" % TEST_STRING, "import binascii"),
)

for no, test in enumerate(tests):
    print "%s - %s" % (no+1, test[0])

    test = timeit.Timer(test[0], test[1])
    print "%.2f" % test.timeit(number=loop)

    print
Ausgaben:
1 - md5.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
1.18

2 - sha.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
1.39

3 - binascii.crc32('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
0.57
Also binascii.crc32 ist am schnellsten. Allerdings ist es auch nur eine 32-bit checksum ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten