[New-bugs-announce] [issue25430] speed up ipaddress __contain__ method

Александр Балезин report at bugs.python.org
Sat Oct 17 13:57:18 CEST 2015


New submission from Александр Балезин:

Current check "address in network" is seems a bit odd:
int(self.network_address) <= int(other._ip) < int(self.broadcast_address)
This patch make this in bit-operation manner. Perfomace test:

import ipaddress
import timeit


class IPv6Network2(ipaddress.IPv6Network):
    def __contains__(self, other):
        # always false if one is v4 and the other is v6.
        if self._version != other._version:
            return False
        # dealing with another network.
        if isinstance(other, ipaddress._BaseNetwork):
            return False
        else:
            # address
            return other._ip & self.netmask._ip == self.network_address._ip

class IPv4Network2(ipaddress.IPv4Network):
    def __contains__(self, other):
        # always false if one is v4 and the other is v6.
        if self._version != other._version:
            return False
        # dealing with another network.
        if isinstance(other, ipaddress._BaseNetwork):
            return False
        # dealing with another address
        else:
            # address
            return other._ip & self.netmask._ip == self.network_address._ip

ipv6_test_net = ipaddress.IPv6Network("::/0")
ipv6_test_net2 = IPv6Network2("::/0")
ipv4_test_net = ipaddress.IPv4Network("0.0.0.0/0")
ipv4_test_net2 = IPv4Network2("0.0.0.0/0")

dataipv6 = list()
dataipv4 = list()
for x in range(2000000):
    dataipv6.append(ipaddress.IPv6Address(x))
    dataipv4.append(ipaddress.IPv4Address(x))

def test():
    for d in dataipv6:
        d in ipv6_test_net

def test2():
    for d in dataipv6:
        d in ipv6_test_net2

def test3():
    for d in dataipv4:
        d in ipv4_test_net

def test4():
    for d in dataipv4:
        d in ipv4_test_net2

t = timeit.Timer("test()", "from __main__ import test")
print("ipv6 test origin __contains__", t.timeit(number=1))

t = timeit.Timer("test2()", "from __main__ import test2")
print("ipv6 test new __contains__", t.timeit(number=1))

t = timeit.Timer("test3()", "from __main__ import test3")
print("ipv4 test origin __contains__", t.timeit(number=1))

t = timeit.Timer("test4()", "from __main__ import test4")
print("ipv4 test new __contains__", t.timeit(number=1))

Output:

ipv6 test origin __contains__ 4.265904285013676
ipv6 test new __contains__ 1.551749340025708
ipv4 test origin __contains__ 3.689626455074176
ipv4 test new __contains__ 2.0175559649942443

----------
components: Library (Lib)
files: ipaddress_contains.patch
keywords: patch
messages: 253126
nosy: Александр.Балезин
priority: normal
severity: normal
status: open
title: speed up ipaddress __contain__ method
type: performance
versions: Python 3.5
Added file: http://bugs.python.org/file40801/ipaddress_contains.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25430>
_______________________________________


More information about the New-bugs-announce mailing list