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]