From 86b621b36b1e4d406fc75043930559ef7a1d6da4 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 16 May 2020 04:00:24 +0700 Subject: trx_toolkit/data_msg.py: use list comprehension for bit conversion This approach is much better than buf.append() in terms of performance. Consider the following bit conversion benchmark code: usbits = [random.randint(0, 254) for i in range(GSM_BURST_LEN)] ubits = [int(b > 128) for b in usbits] for i in range(100000): sbits = DATAMSG.usbit2sbit(usbits) assert(DATAMSG.sbit2usbit(sbits) == usbits) sbits = DATAMSG.ubit2sbit(ubits) assert(DATAMSG.sbit2ubit(sbits) == ubits) === Before this patch: 59603795 function calls (59603761 primitive calls) in 11.357 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 59200093 3.389 0.000 3.389 0.000 {method 'append' of 'list' objects} 100000 2.212 0.000 3.062 0.000 data_msg.py:191(usbit2sbit) 100000 1.920 0.000 2.762 0.000 data_msg.py:214(sbit2ubit) 100000 1.835 0.000 2.677 0.000 data_msg.py:204(sbit2usbit) 100000 1.760 0.000 2.613 0.000 data_msg.py:224(ubit2sbit) === After this patch: 803794 function calls (803760 primitive calls) in 3.547 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 100000 1.284 0.000 1.284 0.000 data_msg.py:203() 100000 0.864 0.000 0.864 0.000 data_msg.py:193() 100000 0.523 0.000 0.523 0.000 data_msg.py:198() 100000 0.500 0.000 0.500 0.000 data_msg.py:208() 1 0.237 0.237 3.547 3.547 data_msg.py:25() 100000 0.035 0.000 0.899 0.000 data_msg.py:191(usbit2sbit) 100000 0.035 0.000 0.558 0.000 data_msg.py:196(sbit2usbit) 100000 0.033 0.000 0.533 0.000 data_msg.py:206(ubit2sbit) 100000 0.033 0.000 1.317 0.000 data_msg.py:201(sbit2ubit) So the new implementation is ~70% faster in this case, and takes significantly less function calls according to cProfile [1]. [1] https://docs.python.org/3.8/library/profile.html Change-Id: I01c07160064c8107e5db7d913ac6dec6fc419945 --- src/target/trx_toolkit/data_msg.py | 43 ++++++-------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/src/target/trx_toolkit/data_msg.py b/src/target/trx_toolkit/data_msg.py index 8710702b..35e09d68 100644 --- a/src/target/trx_toolkit/data_msg.py +++ b/src/target/trx_toolkit/data_msg.py @@ -190,45 +190,22 @@ class DATAMSG: # Converts unsigned soft-bits {254..0} to soft-bits {-127..127} @staticmethod def usbit2sbit(bits): - buf = [] - - for bit in bits: - if bit == 0xff: - buf.append(-127) - else: - buf.append(127 - bit) - - return buf + return [-127 if (b == 0xff) else 127 - b for b in bits] # Converts soft-bits {-127..127} to unsigned soft-bits {254..0} @staticmethod def sbit2usbit(bits): - buf = [] - - for bit in bits: - buf.append(127 - bit) - - return buf + return [127 - b for b in bits] # Converts soft-bits {-127..127} to bits {1..0} @staticmethod def sbit2ubit(bits): - buf = [] - - for bit in bits: - buf.append(1 if bit < 0 else 0) - - return buf + return [int(b < 0) for b in bits] # Converts bits {1..0} to soft-bits {-127..127} @staticmethod def ubit2sbit(bits): - buf = [] - - for bit in bits: - buf.append(-127 if bit else 127) - - return buf + return [-127 if b else 127 for b in bits] # Validates the message fields (throws ValueError) def validate(self): @@ -426,11 +403,7 @@ class DATAMSG_L12TRX(DATAMSG): # Generate a random message specific burst def rand_burst(self, length = GSM_BURST_LEN): - self.burst = [] - - for i in range(length): - ubit = random.randint(0, 1) - self.burst.append(ubit) + self.burst = [random.randint(0, 1) for i in range(length)] # Transforms this message to TRX2L1 message def gen_trx2l1(self, ver = None): @@ -836,14 +809,10 @@ class DATAMSG_TRX2L1(DATAMSG): # Generate a random message specific burst def rand_burst(self, length = None): - self.burst = [] - if length is None: length = self.mod_type.bl - for i in range(length): - sbit = random.randint(-127, 127) - self.burst.append(sbit) + self.burst = [random.randint(-127, 127) for i in range(length)] # Transforms this message to L12TRX message def gen_l12trx(self, ver = None): -- cgit v1.2.3