net_utils: Speed up mac address generation

Using getrandbits supposes a huge speedup:

Py2
In [2]: %timeit random.randint(0, 0xff)
The slowest run took 28.53 times longer than the fastest.
This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 769 ns per loop

In [3]: %timeit random.getrandbits(8)
The slowest run took 54.81 times longer than the fastest.
This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 126 ns per loop

Py3

In [3]: %timeit random.randint(0, 0xff)
The slowest run took 288.80 times longer than the fastest.
This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.15 µs per loop

In [4]: %timeit random.getrandbits(8)
The slowest run took 29.15 times longer than the fastest.
This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 109 ns per loop

Change-Id: Id6b86c7d2cf88feb81b79862d93f8d06aeb8fa63
Signed-off-by: Antoni Segura Puimedon <antonisp@celebdor.com>
This commit is contained in:
Antoni Segura Puimedon 2017-10-10 12:01:58 +02:00
parent ff5ee1720d
commit b5b7131f4e
No known key found for this signature in database
GPG Key ID: B71BE48A9A349926
2 changed files with 6 additions and 6 deletions

View File

@ -33,17 +33,17 @@ class TestGetHostname(base.BaseTestCase):
class TestGetRandomMac(base.BaseTestCase):
@mock.patch.object(random, 'randint', return_value=0xa2)
@mock.patch.object(random, 'getrandbits', return_value=0xa2)
def test_first_4_octets_unchanged(self, mock_rnd):
mac = net.get_random_mac(['aa', 'bb', '00', 'dd', 'ee', 'ff'])
self.assertEqual('aa:bb:00:dd:a2:a2', mac)
mock_rnd.assert_called_with(0x00, 0xff)
mock_rnd.assert_called_with(8)
@mock.patch.object(random, 'randint', return_value=0xa2)
@mock.patch.object(random, 'getrandbits', return_value=0xa2)
def test_first_4th_octet_generated(self, mock_rnd):
mac = net.get_random_mac(['aa', 'bb', 'cc', '00', 'ee', 'ff'])
self.assertEqual('aa:bb:cc:a2:a2:a2', mac)
mock_rnd.assert_called_with(0x00, 0xff)
mock_rnd.assert_called_with(8)
class TestPortDeviceOwner(base.BaseTestCase):

View File

@ -36,8 +36,8 @@ def get_random_mac(base_mac):
"""
mac = [int(base_mac[0], 16), int(base_mac[1], 16),
int(base_mac[2], 16), random.randint(0x00, 0xff),
random.randint(0x00, 0xff), random.randint(0x00, 0xff)]
int(base_mac[2], 16), random.getrandbits(8),
random.getrandbits(8), random.getrandbits(8)]
if base_mac[3] != '00':
mac[3] = int(base_mac[3], 16)
return ':'.join(["%02x" % x for x in mac])