This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author xtreak
Recipients gescheit, ncoghlan, pitrou, pmoody, serhiy.storchaka, xtreak
Date 2018-12-16.18:00:02
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1544983202.66.0.788709270274.issue25430@psf.upfronthosting.co.za>
In-reply-to
Content
Though this is out of the scope of the issue I tried converting num_addresses, __hash__, __getitem__ and __eq__ as per Serhiy's idea for IPv6Network replacing the stdlib implementation's int calls with _ip in a custom class. I can see up to 50% speedups as below and no test case failures converting rest of the call sites to use _ip instead of int in stdlib. But some of the methods may not be used as frequently as in this benchmark like thus being not worthy enough of change. Shall I open a new issue for further discussion? 

$ python3.7 bpo25430_1.py

ipv6 test num_addresses with int 1.54065761
ipv6 test num_addresses without int 0.8266360819999998
ipv6 test hash with int 1.320016881
ipv6 test hash without int 0.6266323200000001
ipv6 test equality with int 1.6104001990000008
ipv6 test equality without int 1.0374885390000008
ipv6 test get item with int 2.092343390000001
ipv6 test get item without int 1.5606673410000003

$ bpo25430_1.py

import ipaddress
import timeit

class IPv6Network2(ipaddress.IPv6Network):

    @property
    def num_addresses(self):
        return self.broadcast_address._ip - self.network_address._ip + 1

    def __hash__(self):
        return hash(self.network_address._ip ^ self.netmask._ip)

    def __eq__(self, other):
        try:
            return (self._version == other._version and
                    self.network_address == other.network_address and
                    self.netmask._ip == other.netmask._ip)
        except AttributeError:
            return NotImplemented

    def __getitem__(self, n):
        network = self.network_address._ip
        broadcast = self.broadcast_address._ip
        if n >= 0:
            if network + n > broadcast:
                raise IndexError('address out of range')
            return self._address_class(network + n)
        else:
            n += 1
            if broadcast + n < network:
                raise IndexError('address out of range')
            return self._address_class(broadcast + n)


ipv6_test_net = ipaddress.IPv6Network("::/0")
ipv6_test_net2 = IPv6Network2("::/0")

def test1_num_address():
    return ipv6_test_net.num_addresses

def test2_num_address():
    return ipv6_test_net2.num_addresses

def test1_hash_address():
    return hash(ipv6_test_net)

def test2_hash_address():
    return hash(ipv6_test_net2)

if __name__ == "__main__":
    t = timeit.Timer("test1_num_address()", "from __main__ import test1_num_address")
    print("ipv6 test num_addresses with int", t.timeit(number=1000000))

    t = timeit.Timer("test2_num_address()", "from __main__ import test2_num_address")
    print("ipv6 test num_addresses without int", t.timeit(number=1000000))

    t = timeit.Timer("test1_hash_address()", "from __main__ import test1_hash_address")
    print("ipv6 test hash with int", t.timeit(number=1000000))

    t = timeit.Timer("test2_hash_address()", "from __main__ import test2_hash_address")
    print("ipv6 test hash without int", t.timeit(number=1000000))

    t = timeit.Timer("ipv6_test_net == ipv6_test_net", "from __main__ import ipv6_test_net")
    print("ipv6 test equality with int", t.timeit(number=1000000))

    t = timeit.Timer("ipv6_test_net2 == ipv6_test_net2", "from __main__ import ipv6_test_net2")
    print("ipv6 test equality without int", t.timeit(number=1000000))

    t = timeit.Timer("ipv6_test_net[10000]", "from __main__ import ipv6_test_net")
    print("ipv6 test get item with int", t.timeit(number=1000000))

    t = timeit.Timer("ipv6_test_net2[10000]", "from __main__ import ipv6_test_net2")
    print("ipv6 test get item without int", t.timeit(number=1000000))

    assert test1_num_address() == test2_num_address()
    assert hash(ipv6_test_net2) == hash(ipv6_test_net)
    assert ipv6_test_net2 == ipv6_test_net
    assert ipv6_test_net[10000] == ipv6_test_net2[10000]
History
Date User Action Args
2018-12-16 18:00:02xtreaksetrecipients: + xtreak, ncoghlan, pitrou, pmoody, gescheit, serhiy.storchaka
2018-12-16 18:00:02xtreaksetmessageid: <1544983202.66.0.788709270274.issue25430@psf.upfronthosting.co.za>
2018-12-16 18:00:02xtreaklinkissue25430 messages
2018-12-16 18:00:02xtreakcreate