Skip to content

Commit cf9b882

Browse files
committed
Implement several other hot-path performance improvements:
- return early in get_property() for simple types that do not require additional wrapping - dedent description text once during elaboration rather than multiple times when querying - intern property strings to improve speed of lookups
1 parent ef71241 commit cf9b882

File tree

4 files changed

+24
-16
lines changed

4 files changed

+24
-16
lines changed

src/systemrdl/core/elaborate.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import TYPE_CHECKING, List, Optional, cast
33

44
from ..ast import ASTNode
5-
from .helpers import is_pow2, roundup_pow2, roundup_to
5+
from .helpers import is_pow2, roundup_pow2, roundup_to, dedent_text
66
from .value_normalization import normalize, RefInParameterError
77

88
from .. import component as comp
@@ -39,7 +39,10 @@ def enter_Component(self, node: Node) -> None:
3939
# Evaluate component properties
4040
for prop_name, prop_value in node.inst.properties.items():
4141
if isinstance(prop_value, ASTNode):
42-
node.inst.properties[prop_name] = prop_value.get_value(assignee_node=node)
42+
v = prop_value.get_value(assignee_node=node)
43+
if prop_name == "desc" and node.env.dedent_desc:
44+
v = dedent_text(v)
45+
node.inst.properties[prop_name] = v
4346

4447

4548
def enter_AddressableComponent(self, node: AddressableNode) -> None:

src/systemrdl/node.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -453,18 +453,19 @@ def get_property(self, prop_name: str, **kwargs: Any)-> Any:
453453
# Property WAS indeed assigned by the user
454454
prop_value = self.inst.properties[prop_name]
455455

456+
if isinstance(prop_value, (rdltypes.BuiltinEnum, str, int)):
457+
# Optimization: Exit early to skip comparisons for popular simple return types
458+
return prop_value
456459
if isinstance(prop_value, rdltypes.ComponentRef):
457460
# If this is a hierarchical component reference, convert it to a Node reference
458-
prop_value = prop_value.build_node_ref(self)
459-
elif isinstance(prop_value, rdltypes.PropertyReference):
460-
prop_value = prop_value.get_resolved_ref(self)
461-
elif isinstance(prop_value, list):
461+
return prop_value.build_node_ref(self)
462+
if isinstance(prop_value, rdltypes.PropertyReference):
463+
return prop_value.get_resolved_ref(self)
464+
if isinstance(prop_value, list):
462465
# Inspect array and resolve any references
463-
prop_value = rdltypes.references.resolve_node_refs_in_array(self, prop_value)
464-
elif rdltypes.is_user_struct(type(prop_value)):
465-
prop_value = rdltypes.references.resolve_node_refs_in_struct(self, prop_value)
466-
elif (prop_name == "desc") and self.env.dedent_desc:
467-
prop_value = helpers.dedent_text(prop_value)
466+
return rdltypes.references.resolve_node_refs_in_array(self, prop_value)
467+
if rdltypes.is_user_struct(type(prop_value)):
468+
return rdltypes.references.resolve_node_refs_in_struct(self, prop_value)
468469

469470
return prop_value
470471

src/systemrdl/properties/bases.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import Any, Set, Type, Tuple, TYPE_CHECKING, Optional, Dict
2+
import sys
23

34
from .. import node as m_node
45
from ..ast.ast_node import ASTNode
@@ -33,15 +34,16 @@ class PropertyRule:
3334

3435
def __init__(self, env: 'RDLEnvironment'):
3536
self.env = env
37+
self._name = self.get_name_cls()
3638

3739

3840
@classmethod
3941
def get_name_cls(cls) -> str:
40-
return cls.__name__.replace("Prop_", "")
42+
return sys.intern(cls.__name__.replace("Prop_", ""))
4143

4244

4345
def get_name(self) -> str:
44-
return self.get_name_cls()
46+
return self._name
4547

4648

4749
def assign_value(self, comp_def: 'comp.Component', value: Any, src_ref: 'SourceRefBase') -> None:
@@ -286,7 +288,7 @@ def _get_mutex_properties(group_name: str) -> Set[str]:
286288
if prop_cls.__name__.startswith("Prop_"):
287289
if prop_cls.mutex_group is not None:
288290
if prop_cls.mutex_group not in _MUTEX_PROP_GROUPS:
289-
_MUTEX_PROP_GROUPS[prop_cls.mutex_group] = set()
290-
_MUTEX_PROP_GROUPS[prop_cls.mutex_group].add(prop_cls.get_name_cls())
291+
_MUTEX_PROP_GROUPS[sys.intern(prop_cls.mutex_group)] = set()
292+
_MUTEX_PROP_GROUPS[sys.intern(prop_cls.mutex_group)].add(prop_cls.get_name_cls())
291293

292294
return _MUTEX_PROP_GROUPS[group_name]

src/systemrdl/rdltypes/references.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ def __init__(self, src_ref: Optional['SourceRefBase'], env: 'RDLEnvironment', co
119119
#: property is being referenced.
120120
self.node: Node
121121

122+
self._name = self.get_name()
123+
122124
def __repr__(self) -> str:
123125
return f"<{self.__class__.__qualname__} {self.node.get_path()}->{self.name} at {id(self):#x}>"
124126

@@ -139,7 +141,7 @@ def name(self) -> str:
139141
"""
140142
Name of the property being referenced
141143
"""
142-
return self.get_name()
144+
return self._name
143145

144146
@classmethod
145147
def get_name(cls) -> str:

0 commit comments

Comments
 (0)