Skip to content

Commit d69d191

Browse files
RouslanAA-Turner
andauthored
Improve cross-reference resolution performance in the C++ domain (#11892)
Co-authored-by: Adam Turner <[email protected]>
1 parent 1785fc9 commit d69d191

File tree

4 files changed

+41
-5
lines changed

4 files changed

+41
-5
lines changed

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Features added
2424
* #11803: autodoc: Use an overriden ``__repr__()`` function in an enum,
2525
if defined. Patch by Shengyu Zhang.
2626

27+
* #11892: Improved performance when resolving cross references in cpp domain.
28+
Patch by Rouslan Korneychuk.
29+
2730
Bugs fixed
2831
----------
2932

sphinx/domains/c.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,12 @@ def __init__(self, identifier: str) -> None:
149149
assert len(identifier) != 0
150150
self.identifier = identifier
151151

152-
def __eq__(self, other: Any) -> bool:
153-
return type(other) is ASTIdentifier and self.identifier == other.identifier
152+
# ASTBaseBase already implements this method,
153+
# but specialising it here improves performance
154+
def __eq__(self, other: object) -> bool:
155+
if type(other) is not ASTIdentifier:
156+
return NotImplemented
157+
return self.identifier == other.identifier
154158

155159
def is_anon(self) -> bool:
156160
return self.identifier[0] == '@'
@@ -1448,6 +1452,10 @@ def __init__(self, objectType: str, directiveType: str | None,
14481452
# set by CObject._add_enumerator_to_parent
14491453
self.enumeratorScopedSymbol: Symbol | None = None
14501454

1455+
# the cache assumes that by the time get_newest_id is called, no
1456+
# further changes will be made to this object
1457+
self._newest_id_cache: str | None = None
1458+
14511459
def clone(self) -> ASTDeclaration:
14521460
return ASTDeclaration(self.objectType, self.directiveType,
14531461
self.declaration.clone(), self.semicolon)
@@ -1474,7 +1482,9 @@ def get_id(self, version: int, prefixed: bool = True) -> str:
14741482
return id_
14751483

14761484
def get_newest_id(self) -> str:
1477-
return self.get_id(_max_id, True)
1485+
if self._newest_id_cache is None:
1486+
self._newest_id_cache = self.get_id(_max_id, True)
1487+
return self._newest_id_cache
14781488

14791489
def _stringify(self, transform: StringifyTransform) -> str:
14801490
res = transform(self.declaration)

sphinx/domains/cpp.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,13 @@ def __init__(self, identifier: str) -> None:
615615
assert len(identifier) != 0
616616
self.identifier = identifier
617617

618+
# ASTBaseBase already implements this method,
619+
# but specialising it here improves performance
620+
def __eq__(self, other: object) -> bool:
621+
if type(other) is not ASTIdentifier:
622+
return NotImplemented
623+
return self.identifier == other.identifier
624+
618625
def _stringify(self, transform: StringifyTransform) -> str:
619626
return transform(self.identifier)
620627

@@ -4018,6 +4025,10 @@ def __init__(self, objectType: str, directiveType: str | None = None,
40184025
# set by CPPObject._add_enumerator_to_parent
40194026
self.enumeratorScopedSymbol: Symbol | None = None
40204027

4028+
# the cache assumes that by the time get_newest_id is called, no
4029+
# further changes will be made to this object
4030+
self._newest_id_cache: str | None = None
4031+
40214032
def clone(self) -> ASTDeclaration:
40224033
templatePrefixClone = self.templatePrefix.clone() if self.templatePrefix else None
40234034
trailingRequiresClasueClone = self.trailingRequiresClause.clone() \
@@ -4083,7 +4094,9 @@ def get_id(self, version: int, prefixed: bool = True) -> str:
40834094
return ''.join(res)
40844095

40854096
def get_newest_id(self) -> str:
4086-
return self.get_id(_max_id, True)
4097+
if self._newest_id_cache is None:
4098+
self._newest_id_cache = self.get_id(_max_id, True)
4099+
return self._newest_id_cache
40874100

40884101
def _stringify(self, transform: StringifyTransform) -> str:
40894102
res = []

sphinx/util/cfamily.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class NoOldIdError(Exception):
8888

8989

9090
class ASTBaseBase:
91-
def __eq__(self, other: Any) -> bool:
91+
def __eq__(self, other: object) -> bool:
9292
if type(self) is not type(other):
9393
return False
9494
try:
@@ -145,6 +145,11 @@ def __init__(self, name: str, args: ASTBaseParenExprList | None) -> None:
145145
self.name = name
146146
self.args = args
147147

148+
def __eq__(self, other: object) -> bool:
149+
if type(other) is not ASTGnuAttribute:
150+
return NotImplemented
151+
return self.name == other.name and self.args == other.args
152+
148153
def _stringify(self, transform: StringifyTransform) -> str:
149154
res = [self.name]
150155
if self.args:
@@ -204,6 +209,11 @@ class ASTAttributeList(ASTBaseBase):
204209
def __init__(self, attrs: list[ASTAttribute]) -> None:
205210
self.attrs = attrs
206211

212+
def __eq__(self, other: object) -> bool:
213+
if type(other) is not ASTAttributeList:
214+
return NotImplemented
215+
return self.attrs == other.attrs
216+
207217
def __len__(self) -> int:
208218
return len(self.attrs)
209219

0 commit comments

Comments
 (0)