Functional schmunctional...
bearophileHUGS at lycos.com
bearophileHUGS at lycos.com
Tue Feb 10 16:52:11 EST 2009
Here a small benchmark:
def ip2inet01(a): # can't be used with 6
li = a.split('.')
assert len(li) == 4
a = int(li[0])*16777216
b = int(li[1])*65536
c = int(li[2])*256
d = int(li[3])
return a+b+c+d
from itertools import count
def ip2inet02(a):
blocks = a.split('.')
assert len(blocks) in (4, 6)
return sum(map(lambda (i, n): int(i) * 256**n, zip(reversed
(blocks), count(0))))
def ip2inet03(iptxt):
bytes = map(int, iptxt.strip().split("."))[::-1]
assert len(bytes) in (4, 6)
return sum(by * 256**po for po, by in enumerate(bytes))
def ip2inet04(iptxt):
bytes = map(int, reversed(iptxt.strip().split(".")))
assert len(bytes) in (4, 6)
powers256 = [1, 256, 65536, 16777216, 4294967296, 1099511627776]
return sum(by * powers256[po] for po, by in enumerate(bytes))
def ip2inet05(iptxt):
bytes = (int(by) for by in reversed(iptxt.strip().split(".")))
parts = [by * ip2inet05.powers256[po] for po, by in enumerate
(bytes)]
assert len(parts) in (4, 6)
return sum(parts)
ip2inet05.powers256 = [1, 256, 65536, 16777216, 4294967296,
1099511627776]
def ip2inet06(a):
li = a.split('.')
n = len(li)
assert n == 4 or n == 6
if n == 4:
return (int(li[0]) * 16777216 +
int(li[1]) * 65536 +
int(li[2]) * 256 +
int(li[3]))
else:
return (int(li[0]) * 1099511627776 +
int(li[1]) * 4294967296 +
int(li[2]) * 16777216 +
int(li[3]) * 65536 +
int(li[4]) * 256 +
int(li[5]))
def ip2inet07(iptxt):
bytes = map(int, iptxt.strip().split("."))[::-1]
assert len(bytes) in (4, 6)
return sum(by * ip2inet07.pows[po] for po, by in enumerate(bytes))
ip2inet07.pows = [1, 256, 65536, 16777216, 4294967296, 1099511627776]
from struct import pack
def ip2inet08(n): # error
xs = pack('L', n)
return '.'.join(str(ord(x)) for x in xs)
def ip2inet09(iptxt): # short and readable
bytes = map(int, iptxt.strip().split("."))[::-1]
assert len(bytes) in (4, 6)
return sum(by << (8*po) for po, by in enumerate(bytes))
def ip2inet10(iptxt):
count = 0
result = 0
for byte in iptxt.strip().split("."):
result <<= 8
result += int(byte)
count += 1
assert count in (4, 6)
return result
def ip2inet11(iptxt):
bytes = iptxt.strip().split(".")
assert len(bytes) in (4, 6)
result = 0
for byte in bytes:
result <<= 8
result += int(byte)
return result
def ip2inet12(iptxt):
bytes = iptxt.strip().split(".")
assert len(bytes) in (4, 6)
result = 0
for byte in bytes:
result = (result << 8) + int(byte)
return result
def ip2inet13(a): # fastest and readable
li = a.split('.')
n = len(li)
assert n == 4 or n == 6
if n == 4:
return ((int(li[0]) << 24) +
(int(li[1]) << 16) +
(int(li[2]) << 8) +
int(li[3]))
else:
return ((int(li[0]) << 40) +
(int(li[1]) << 32) +
(int(li[2]) << 24) +
(int(li[3]) << 16) +
(int(li[4]) << 8) +
int(li[5]))
def main():
from timeit import default_timer as clock
ip4 = "155.16.187.87"
ip6 = "7.155.16.187.87.255"
algos = [ip2inet02, ip2inet03, ip2inet04, ip2inet05, ip2inet06,
ip2inet07, ip2inet09, ip2inet10, ip2inet11, ip2inet12,
ip2inet13]
for algo in algos:
assert algo(ip4) == 2601565015 and algo(ip6) == 8362582038527
t0 = clock()
for i in xrange(10000):
algo(ip4)
algo(ip6)
print algo.__name__, round(clock() - t0, 2), "s"
import psyco; psyco.full()
print "With Psyco:"
for algo in algos:
t0 = clock()
for i in xrange(10000):
algo(ip4)
algo(ip6)
print algo.__name__, round(clock() - t0, 2), "s"
main()
ip2inet02 2.68 s
ip2inet03 1.79 s
ip2inet04 1.72 s
ip2inet05 1.88 s
ip2inet06 0.98 s
ip2inet07 1.57 s
ip2inet09 1.5 s
ip2inet10 1.07 s
ip2inet11 1.07 s
ip2inet12 1.03 s
ip2inet13 0.95 s
With Psyco (indipendent run! Not normally successive):
ip2inet02 2.66 s
ip2inet03 1.66 s
ip2inet04 1.97 s
ip2inet05 1.66 s
ip2inet06 0.57 s
ip2inet07 1.5 s
ip2inet09 1.54 s
ip2inet10 0.53 s
ip2inet11 0.76 s
ip2inet12 0.52 s
ip2inet13 0.8 s
So if you need speed you the version #13 is better, if you want short
and readable code (but not too much slow) you can use #9, and if you
want code easy to understand by every one and easy to translate to
other languages then you can use #12.
Bye,
bearophile
More information about the Python-list
mailing list