Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit 2ec6ea6

Browse files
authored
perf: collisions don't contain reserved names by default (#684)
The 'collisions' set does NOT contain RESERVED_NAMES; they are combined at runtime when needed. For a large real-world, this results in an order of magnitude reduction in memory usage. I'm not joking: Google Ads v5 uses 2.45 GB peak before this change and 223 MB after. Also contains changes to add `__slots__` attributes to Metadata and Address. These are ancillary, optional, and open to negotiation. In the above scenario, they reduce memory usage from 223 MB to 177 MB. If other people feel that the reduction in readability does not warrant the reduction in memory usage I am absolutely open to dropping that particular commit. Includes other minor memory usage optimizations that collectively shave about 5 MB.
1 parent 18425e2 commit 2ec6ea6

2 files changed

Lines changed: 12 additions & 9 deletions

File tree

gapic/schema/metadata.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ class Address:
4949
)
5050
collisions: FrozenSet[str] = dataclasses.field(default_factory=frozenset)
5151

52-
def __post_init__(self):
53-
super().__setattr__("collisions", self.collisions | RESERVED_NAMES)
54-
5552
def __eq__(self, other) -> bool:
5653
return all([getattr(self, i) == getattr(other, i) for i
5754
in ('name', 'module', 'module_path', 'package', 'parent')])
@@ -114,7 +111,7 @@ def module_alias(self) -> str:
114111
while still providing names that are fundamentally readable
115112
to users (albeit looking auto-generated).
116113
"""
117-
if self.module in self.collisions:
114+
if self.module in self.collisions | RESERVED_NAMES:
118115
return '_'.join(
119116
(
120117
''.join(
@@ -283,7 +280,7 @@ def with_context(self, *, collisions: FrozenSet[str]) -> 'Address':
283280
``Address`` object aliases module names to avoid naming collisions in
284281
the file being written.
285282
"""
286-
return dataclasses.replace(self, collisions=frozenset(collisions))
283+
return dataclasses.replace(self, collisions=collisions)
287284

288285

289286
@dataclasses.dataclass(frozen=True)

gapic/schema/wrappers.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,19 @@ def recursive_field_types(self) -> Sequence[
314314
return tuple(types)
315315

316316
@utils.cached_property
317-
def recursive_fields(self) -> FrozenSet[Field]:
318-
return frozenset(chain(
317+
def recursive_resource_fields(self) -> FrozenSet[Field]:
318+
all_fields = chain(
319319
self.fields.values(),
320320
(field
321321
for t in self.recursive_field_types if isinstance(t, MessageType)
322322
for field in t.fields.values()),
323-
))
323+
)
324+
return frozenset(
325+
f
326+
for f in all_fields
327+
if (f.options.Extensions[resource_pb2.resource_reference].type or
328+
f.options.Extensions[resource_pb2.resource_reference].child_type)
329+
)
324330

325331
@property
326332
def map(self) -> bool:
@@ -1060,7 +1066,7 @@ def gen_resources(message):
10601066
yield type_
10611067

10621068
def gen_indirect_resources_used(message):
1063-
for field in message.recursive_fields:
1069+
for field in message.recursive_resource_fields:
10641070
resource = field.options.Extensions[
10651071
resource_pb2.resource_reference]
10661072
resource_type = resource.type or resource.child_type

0 commit comments

Comments
 (0)