<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmocom-bb/+/18324">View Change</a></p><div style="white-space:pre-wrap">Approvals:
laforge: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
Jenkins Builder: Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">trx_toolkit/data_msg.py: use list comprehension for bit conversion<br><br>This approach is much better than buf.append() in terms of performance.<br>Consider the following bit conversion benchmark code:<br><br> usbits = [random.randint(0, 254) for i in range(GSM_BURST_LEN)]<br> ubits = [int(b > 128) for b in usbits]<br><br> for i in range(100000):<br> sbits = DATAMSG.usbit2sbit(usbits)<br> assert(DATAMSG.sbit2usbit(sbits) == usbits)<br><br> sbits = DATAMSG.ubit2sbit(ubits)<br> assert(DATAMSG.sbit2ubit(sbits) == ubits)<br><br>=== Before this patch:<br><br> 59603795 function calls (59603761 primitive calls) in 11.357 seconds<br><br> Ordered by: internal time<br><br> ncalls tottime percall cumtime percall filename:lineno(function)<br> 59200093 3.389 0.000 3.389 0.000 {method 'append' of 'list' objects}<br> 100000 2.212 0.000 3.062 0.000 data_msg.py:191(usbit2sbit)<br> 100000 1.920 0.000 2.762 0.000 data_msg.py:214(sbit2ubit)<br> 100000 1.835 0.000 2.677 0.000 data_msg.py:204(sbit2usbit)<br> 100000 1.760 0.000 2.613 0.000 data_msg.py:224(ubit2sbit)<br><br>=== After this patch:<br><br> 803794 function calls (803760 primitive calls) in 3.547 seconds<br><br> Ordered by: internal time<br><br> ncalls tottime percall cumtime percall filename:lineno(function)<br> 100000 1.284 0.000 1.284 0.000 data_msg.py:203(<listcomp>)<br> 100000 0.864 0.000 0.864 0.000 data_msg.py:193(<listcomp>)<br> 100000 0.523 0.000 0.523 0.000 data_msg.py:198(<listcomp>)<br> 100000 0.500 0.000 0.500 0.000 data_msg.py:208(<listcomp>)<br> 1 0.237 0.237 3.547 3.547 data_msg.py:25(<module>)<br> 100000 0.035 0.000 0.899 0.000 data_msg.py:191(usbit2sbit)<br> 100000 0.035 0.000 0.558 0.000 data_msg.py:196(sbit2usbit)<br> 100000 0.033 0.000 0.533 0.000 data_msg.py:206(ubit2sbit)<br> 100000 0.033 0.000 1.317 0.000 data_msg.py:201(sbit2ubit)<br><br>So the new implementation is ~70% faster in this case, and takes<br>significantly less function calls according to cProfile [1].<br><br>[1] https://docs.python.org/3.8/library/profile.html<br><br>Change-Id: I01c07160064c8107e5db7d913ac6dec6fc419945<br>---<br>M src/target/trx_toolkit/data_msg.py<br>1 file changed, 6 insertions(+), 37 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/trx_toolkit/data_msg.py b/src/target/trx_toolkit/data_msg.py</span><br><span>index 8710702..35e09d6 100644</span><br><span>--- a/src/target/trx_toolkit/data_msg.py</span><br><span>+++ b/src/target/trx_toolkit/data_msg.py</span><br><span>@@ -190,45 +190,22 @@</span><br><span> # Converts unsigned soft-bits {254..0} to soft-bits {-127..127}</span><br><span> @staticmethod</span><br><span> def usbit2sbit(bits):</span><br><span style="color: hsl(0, 100%, 40%);">- buf = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for bit in bits:</span><br><span style="color: hsl(0, 100%, 40%);">- if bit == 0xff:</span><br><span style="color: hsl(0, 100%, 40%);">- buf.append(-127)</span><br><span style="color: hsl(0, 100%, 40%);">- else:</span><br><span style="color: hsl(0, 100%, 40%);">- buf.append(127 - bit)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return buf</span><br><span style="color: hsl(120, 100%, 40%);">+ return [-127 if (b == 0xff) else 127 - b for b in bits]</span><br><span> </span><br><span> # Converts soft-bits {-127..127} to unsigned soft-bits {254..0}</span><br><span> @staticmethod</span><br><span> def sbit2usbit(bits):</span><br><span style="color: hsl(0, 100%, 40%);">- buf = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for bit in bits:</span><br><span style="color: hsl(0, 100%, 40%);">- buf.append(127 - bit)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return buf</span><br><span style="color: hsl(120, 100%, 40%);">+ return [127 - b for b in bits]</span><br><span> </span><br><span> # Converts soft-bits {-127..127} to bits {1..0}</span><br><span> @staticmethod</span><br><span> def sbit2ubit(bits):</span><br><span style="color: hsl(0, 100%, 40%);">- buf = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for bit in bits:</span><br><span style="color: hsl(0, 100%, 40%);">- buf.append(1 if bit < 0 else 0)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return buf</span><br><span style="color: hsl(120, 100%, 40%);">+ return [int(b < 0) for b in bits]</span><br><span> </span><br><span> # Converts bits {1..0} to soft-bits {-127..127}</span><br><span> @staticmethod</span><br><span> def ubit2sbit(bits):</span><br><span style="color: hsl(0, 100%, 40%);">- buf = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for bit in bits:</span><br><span style="color: hsl(0, 100%, 40%);">- buf.append(-127 if bit else 127)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return buf</span><br><span style="color: hsl(120, 100%, 40%);">+ return [-127 if b else 127 for b in bits]</span><br><span> </span><br><span> # Validates the message fields (throws ValueError)</span><br><span> def validate(self):</span><br><span>@@ -426,11 +403,7 @@</span><br><span> </span><br><span> # Generate a random message specific burst</span><br><span> def rand_burst(self, length = GSM_BURST_LEN):</span><br><span style="color: hsl(0, 100%, 40%);">- self.burst = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for i in range(length):</span><br><span style="color: hsl(0, 100%, 40%);">- ubit = random.randint(0, 1)</span><br><span style="color: hsl(0, 100%, 40%);">- self.burst.append(ubit)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.burst = [random.randint(0, 1) for i in range(length)]</span><br><span> </span><br><span> # Transforms this message to TRX2L1 message</span><br><span> def gen_trx2l1(self, ver = None):</span><br><span>@@ -836,14 +809,10 @@</span><br><span> </span><br><span> # Generate a random message specific burst</span><br><span> def rand_burst(self, length = None):</span><br><span style="color: hsl(0, 100%, 40%);">- self.burst = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> if length is None:</span><br><span> length = self.mod_type.bl</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- for i in range(length):</span><br><span style="color: hsl(0, 100%, 40%);">- sbit = random.randint(-127, 127)</span><br><span style="color: hsl(0, 100%, 40%);">- self.burst.append(sbit)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.burst = [random.randint(-127, 127) for i in range(length)]</span><br><span> </span><br><span> # Transforms this message to L12TRX message</span><br><span> def gen_l12trx(self, ver = None):</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmocom-bb/+/18324">change 18324</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmocom-bb/+/18324"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I01c07160064c8107e5db7d913ac6dec6fc419945 </div>
<div style="display:none"> Gerrit-Change-Number: 18324 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>