Unpacking data with minimal effort:
The bit shifting is nice to learn more about low-level stuff, but later you want to use more high-level stuff where you can make lesser errors. Premature optimization is the root of all evil. If you think your code runs too slow, measure it. Then find the spot where your code runs slow. Then you can optimize. In the most cases of getting input from something, the speed of Python is fast enough to process it with high-level constructs like the Struct class. Calling the functions directly, without the class instance, does not show a measurable difference in Speed with Python 3.10 on my desktop. Older Python Versions may have more significant differences of calling functions directly or methods of instances.
The measurement of time could be done with
Not to use the
A class could also attach the delays to the instance, but this requires the understanding of OOP and the Python object model.
from struct import Struct from random import randint # little endian, 512 unsigned integers (4 bytes per int; 32 bit) DataFormat = Struct("<512I") # no fancy multiplication of "I" # simulated incoming random data random_data = bytes(randint(0, 255) for _ in range(2048)) # decoded data decoded = DataFormat.unpack(random_data)You should read the format specification of struct:
- https://docs.python.org/3/library/struct...-alignment
- https://docs.python.org/3/library/struct...characters
The bit shifting is nice to learn more about low-level stuff, but later you want to use more high-level stuff where you can make lesser errors. Premature optimization is the root of all evil. If you think your code runs too slow, measure it. Then find the spot where your code runs slow. Then you can optimize. In the most cases of getting input from something, the speed of Python is fast enough to process it with high-level constructs like the Struct class. Calling the functions directly, without the class instance, does not show a measurable difference in Speed with Python 3.10 on my desktop. Older Python Versions may have more significant differences of calling functions directly or methods of instances.
The measurement of time could be done with
time.perf_counter()
, because this timer has a higher resolution and there is a guarantee, that this timer will never go backwards. With a context manager, it's like magic:from contextlib import contextmanager @contextmanager def measure_time(results: list): """ This context manager measures the time in the with-block and adds the time to the given list `results` """ start = time.perf_counter() yield stop = time.perf_counter() results.append(stop - start) # code which uses measure_time delays = [] for _ in range(10): with measure_time(delays): time.sleep(1) print(delays)The benefit is, that the timing logic is separated from user code. This implementation is the simplest way.
Not to use the
datetime
module, saves the conversion back and forth.A class could also attach the delays to the instance, but this requires the understanding of OOP and the Python object model.
import time class MeasureTime: def __init__(self): self._delays = [] self._last_start = 0.0 def __enter__(self): """ This context manager measures the time in the with-block and adds the time to delays """ self._last_start = time.perf_counter() def __exit__(self, exception_type, exception_value, exception_traceback): self._delays.append(time.perf_counter() - self._last_start) @property def delays(self): """ Write protected delays of last usages as a tuple. """ return tuple(self._delays) def clear(self): """ Delete all measured delays """ self._delays.clear() # later in code measure_time = MeasureTime() with measure_time: time.sleep(1) with measure_time: time.sleep(0.001) # 1 ms print(measure_time.delays) print("Clearing delays") measure_time.clear() print("One single measurement") with measure_time: time.sleep(0.005) print(measure_time.delays)PS: Please do not compare with timeit because this module repeats functions x times to get an average time and the standard deviation. The code I posted is used to measure how long something takes at individual points in the code.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
All humans together. We don't need politicians!