Seite 1 von 1
IP in IPNUMBER umwandeln (Skript optimieren)
Verfasst: Montag 16. März 2009, 15:19
von bcit6k
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
Verfasst: Montag 16. März 2009, 15:32
von DasIch
`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.
Verfasst: Montag 16. März 2009, 15:43
von bcit6k
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
Verfasst: Montag 16. März 2009, 15:43
von Leonidas
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.
Verfasst: Montag 16. März 2009, 15:53
von Dauerbaustelle
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.
Verfasst: Montag 16. März 2009, 16:02
von veers
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.
Verfasst: Montag 16. März 2009, 18:54
von hendrikS
Wenn es um Speed geht, könnte man vielleicht auch mit dem << Operator arbeiten. Ich glaube, der ist schneller als Multiplizieren oder Potenzieren.
Verfasst: Montag 16. März 2009, 19:46
von Dauerbaustelle
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...
Verfasst: Dienstag 17. März 2009, 10:01
von hendrikS
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
Verfasst: Donnerstag 19. März 2009, 13:30
von Trundle
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]