IP in IPNUMBER umwandeln (Skript optimieren)

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
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Montag 16. März 2009, 15:19

Hallo,

ich habe ein Skript das IP Adressen in IP Nummern umwandelt. Ist eigentlich ein schicker 3 Zeiler. Aber leider dauert er zu lange.

Code: Alles auswählen

ipnumber = "";
				iparray = IP.split(".")    
				ipnumber = int(iparray[0])*int(16777216)+int(iparray[1])*int(65536)+int(iparray[2])*int(256)+int(iparray[3])
Ich habe ein paar nachmessungen angestellt und habe für diesen schritt eine Zeit von ca 277 msek bekommen. Bei einer umrechnung von 3 Millionen Werten dauert das dann schon mal.

gibt es eine bessere (schnellere) funktion als split?

Danke für die hilfe
DasIch
User
Beiträge: 2437
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Montag 16. März 2009, 15:32

`int(1)` ist unnötig, `1` reicht. str.split gibt kein array zurück und ist eine Methode und keine Funktion. Eine Alternative gibt es dazu auch nicht, vorallem keine schnellere. Wenn du wirklich was schnelleres brauchst solltest du nicht Python nutzen.
bcit6k
User
Beiträge: 77
Registriert: Mittwoch 23. Juli 2008, 08:50

Montag 16. März 2009, 15:43

hallo,

danke für den tipp, leider hab ich nun alles schon in python.
ich werd mal versuchen den sql string der die ip ermittelt so um zu bauen das er mir schon die teilstücke liefert

;)
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 16. März 2009, 15:43

Schneller könnte es sein, wenn man den Strin Zeichenweise durchgeht und mit einem Speicher arbeitet auf dem man die Werte zusammensammelt bis ein Punkt kommt, und das ganze für jedes Oktet.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Montag 16. März 2009, 15:53

Wie wärs damit:

Code: Alles auswählen

IP = "127.0.0.1"
splitted_ip = [int(part) for part in IP.split('.')]
ip_number = sum([a*b for a, b in zip(splitted_ip, (16777216, 65536, 256, 1))])
Oder als Einzeiler:

Code: Alles auswählen

ip_number = sum([int(a)*b for a, b in zip(IP.split('.'), (16777216, 65536, 256, 1))])
Ist aber noch langsamer.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Montag 16. März 2009, 16:02

Code: Alles auswählen

sum(int(n)*(2**(8*i)) for i, n in enumerate(reversed(ip.split("."))))
ist etwa halb so schnell wie dein Ansatz aber doppelt so cool ;)
Aber mit 7.7µs pro Aufruf immer noch schnell genug ;)

Aber eigentlich reicht socket.inet_aton würde dir die ip noch als 4 bytes zurück geben.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Montag 16. März 2009, 18:54

Wenn es um Speed geht, könnte man vielleicht auch mit dem << Operator arbeiten. Ich glaube, der ist schneller als Multiplizieren oder Potenzieren.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Montag 16. März 2009, 19:46

Ey ich weiß ja nicht, wen interessieren eigentlich 10 Millisekunden? Ich meine, wenn man das Gefühl hat, das Programm wäre zu langsam, dann kann man bestimmt irgendwo anders optimieren, an Stellen wo man mit Umschreiben des Codes eventuell 500 Millisekunden oder 1 Sekunde oder gar mehr pro Schleifendurchlauf o.ä. Speedup bekommt...
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Dienstag 17. März 2009, 10:01

Kleinvieh macht auch Mist. Hier meine Lösung. Vielleicht nicht besonders cool aber effizient.

Code: Alles auswählen

def ip2num(ip):
    ip = ip.split('.')
    num = int(ip.pop(0))
    while ip:num = (num<<8) | int(ip.pop(0))
    return num
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Donnerstag 19. März 2009, 13:30

Das bereits von veers vorgeschlagene `socket.inet_aton()` ist viel schneller.

Code: Alles auswählen

from socket import inet_aton
from struct import unpack

def ip2num(ip):
    return unpack('!I', inet_aton(ip))[0]
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Antworten