Closed pavel-kirienko closed 3 years ago
The package is slow to import. This is bad because it affects the performance of CLI tools that rely on it, among other things. Import profiling (set -x PYTHONPROFILEIMPORTTIME 1) shows that most of the time is spent importing pydsdl._parser:
set -x PYTHONPROFILEIMPORTTIME 1
pydsdl._parser
import time: 363 | 363 | pydsdl._error import time: 440 | 440 | numbers import time: 799 | 1239 | _decimal import time: 189 | 1427 | decimal import time: 237 | 237 | math import time: 1711 | 3374 | fractions import time: 199 | 199 | unicodedata import time: 490 | 4062 | pydsdl._expression._primitive import time: 377 | 4802 | pydsdl._expression._any import time: 531 | 531 | pydsdl._expression._operator import time: 581 | 1111 | pydsdl._expression._container import time: 261 | 6173 | pydsdl._expression import time: 448 | 448 | pydsdl._bit_length_set import time: 342 | 6961 | pydsdl._serializable._serializable import time: 694 | 694 | pydsdl._serializable._primitive import time: 264 | 264 | pydsdl._serializable._void import time: 405 | 405 | pydsdl._serializable._array import time: 149 | 149 | pydsdl._port_id_ranges import time: 186 | 186 | pydsdl._serializable._name import time: 327 | 512 | pydsdl._serializable._attribute import time: 1055 | 1716 | pydsdl._serializable._composite import time: 260 | 10297 | pydsdl._serializable import time: 212 | 212 | __future__ import time: 1397 | 1608 | six import time: 85 | 85 | _ast import time: 282 | 366 | ast import time: 191 | 556 | parsimonious.utils import time: 321 | 2485 | parsimonious.exceptions import time: 47 | 47 | six.moves import time: 387 | 387 | parsimonious.nodes import time: 468 | 901 | parsimonious.expressions import time: 15945 | 16845 | parsimonious.grammar import time: 194 | 19524 | parsimonious import time: 37296 | 56819 | pydsdl._parser import time: 409 | 57228 | pydsdl._dsdl_definition import time: 805 | 71175 | pydsdl._namespace import time: 436 | 71610 | pydsdl
Without further analysis I predict that the culprit is right here:
https://github.com/UAVCAN/pydsdl/blob/cb35ad3e8c0886d44facdfac14489b9ba7999d44/pydsdl/_parser.py#L140-L142
We parse the grammar definition at the time of package initialization. This is not great. Consider implementing lazy initialization:
@functools.lru_cache(None) def _get_grammar() -> parsimonious.Grammar: ...
The package is slow to import. This is bad because it affects the performance of CLI tools that rely on it, among other things. Import profiling (
set -x PYTHONPROFILEIMPORTTIME 1
) shows that most of the time is spent importingpydsdl._parser
:Without further analysis I predict that the culprit is right here:
https://github.com/UAVCAN/pydsdl/blob/cb35ad3e8c0886d44facdfac14489b9ba7999d44/pydsdl/_parser.py#L140-L142
We parse the grammar definition at the time of package initialization. This is not great. Consider implementing lazy initialization: