From 39b9eb842701671d4662e5c9811259880b22884a Mon Sep 17 00:00:00 2001 From: Angus Stewart Date: Sun, 14 Sep 2025 14:56:40 +0000 Subject: [PATCH] feat: Pre-compile struct --- src/pybag/encoding/cdr.py | 97 ++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 57 deletions(-) diff --git a/src/pybag/encoding/cdr.py b/src/pybag/encoding/cdr.py index 1dfa414..ecf986c 100644 --- a/src/pybag/encoding/cdr.py +++ b/src/pybag/encoding/cdr.py @@ -20,94 +20,77 @@ def __init__(self, data: bytes): # Skip first 4 bytes self._data = BytesReader(data[4:]) + # Pre-compiled primitive struct parsers + self._primitive_parsers = { + 'bool': struct.Struct('?'), + 'int8': struct.Struct('b'), + 'uint8': struct.Struct('B'), + 'char': struct.Struct('c'), + 'int16': struct.Struct('h'), + 'uint16': struct.Struct('H'), + 'int32': struct.Struct('i'), + 'uint32': struct.Struct('I'), + 'int64': struct.Struct('q'), + 'uint64': struct.Struct('Q'), + 'float32': struct.Struct('f'), + 'float64': struct.Struct('d'), + } + def parse(self, type_str: str) -> Any: return getattr(self, type_str)() # Primitive parsers ------------------------------------------------- def bool(self) -> bool: - value = struct.unpack('?', self._data.align(1).read(1))[0] - return value + bool_data = self._data.align(1).read(1) + return self._primitive_parsers['bool'].unpack(bool_data)[0] def int8(self) -> int: - value = struct.unpack( - 'b', - self._data.align(1).read(1) - )[0] - return value + int8_data = self._data.align(1).read(1) + return self._primitive_parsers['int8'].unpack(int8_data)[0] def uint8(self) -> int: - value = struct.unpack( - 'B', - self._data.align(1).read(1) - )[0] - return value + uint8_data = self._data.align(1).read(1) + return self._primitive_parsers['uint8'].unpack(uint8_data)[0] def byte(self) -> bytes: return self._data.align(1).read(1) def char(self) -> str: - value = struct.unpack( - 'c', - self._data.align(1).read(1) - )[0] - return value.decode() + char_data = self._data.align(1).read(1) + return self._primitive_parsers['char'].unpack(char_data)[0].decode() def int16(self) -> int: - value = struct.unpack( - 'h', - self._data.align(2).read(2) - )[0] - return value + int16_data = self._data.align(2).read(2) + return self._primitive_parsers['int16'].unpack(int16_data)[0] def uint16(self) -> int: - value = struct.unpack( - 'H', - self._data.align(2).read(2) - )[0] - return value + uint16_data = self._data.align(2).read(2) + return self._primitive_parsers['uint16'].unpack(uint16_data)[0] def int32(self) -> int: - value = struct.unpack( - 'i', - self._data.align(4).read(4) - )[0] - return value + int32_data = self._data.align(4).read(4) + return self._primitive_parsers['int32'].unpack(int32_data)[0] def uint32(self) -> int: - value = struct.unpack( - 'I', - self._data.align(4).read(4) - )[0] - return value + uint32_data = self._data.align(4).read(4) + return self._primitive_parsers['uint32'].unpack(uint32_data)[0] def int64(self) -> int: - value = struct.unpack( - 'q', - self._data.align(8).read(8) - )[0] - return value + int64_data = self._data.align(8).read(8) + return self._primitive_parsers['int64'].unpack(int64_data)[0] def uint64(self) -> int: - value = struct.unpack( - 'Q', - self._data.align(8).read(8) - )[0] - return value + uint64_data = self._data.align(8).read(8) + return self._primitive_parsers['uint64'].unpack(uint64_data)[0] def float32(self) -> float: - value = struct.unpack( - 'f', - self._data.align(4).read(4) - )[0] - return value + float32_data = self._data.align(4).read(4) + return self._primitive_parsers['float32'].unpack(float32_data)[0] def float64(self) -> float: - value = struct.unpack( - 'd', - self._data.align(8).read(8) - )[0] - return value + float64_data = self._data.align(8).read(8) + return self._primitive_parsers['float64'].unpack(float64_data)[0] def string(self) -> str: # Strings are null-terminated