Commit 8a1270c
authored
feat: implement native PEP 0810 lazy loading (#17591)
## Overview
This is an initiative to resolve severe initialization bottlenecks
(~10s-13s) in generated client libraries by adopting **Native Python
3.15 Explicit Lazy Imports (PEP 0810)**.
To avoid introducing maintenance burdens or subtle breaking changes via
custom import hooks, this PR focuses *exclusively* on utilizing native
interpreter standards.
### Implementation Architecture
We modify the upstream GAPIC Generator to emit a native
`__lazy_modules__` set at the top of the `__init__.py` files,
immediately followed by the standard eager imports.
* **Python 3.15+ (Native Acceleration):** The Python 3.15 runtime
natively intercepts the standard imports referenced in the
`__lazy_modules__` set and treats them as fast C-level lazy proxies.
Startup times drop from ~13s to ~200ms, and peak RAM consumption drops
by up to 85%.
* **Python 3.14 and Older (Zero Blast Radius):** Older Python
environments safely ignore the `__lazy_modules__` variable and process
the standard eager imports exactly as they do today. This guarantees
100% backwards compatibility with zero risk.
* **Perfect Static Typing:** Because standard imports are still present
in the file, IDEs (IntelliSense) and static analyzers (MyPy) maintain
zero-friction support.
**Example Structure:**
```python
# 1. Native C-Level Lazy Proxying for Python 3.15+ (PEP 0810)
__lazy_modules__ = {
f"{__name__}.services.accelerator_types",
f"{__name__}.services.addresses",
f"{__name__}.types.compute",
}
# 2. Standard eager imports
# Evaluated instantly by older Python versions. Intercepted natively by Python 3.15.
from .services.accelerator_types import AcceleratorTypesClient
from .services.addresses import AddressesClient
from .types.compute import Address
__all__ = (
"AcceleratorTypesClient",
"AddressesClient",
"Address",
)
```
## 🚀 Performance Benchmarking Results (Disk-Level Cold Start)
We utilized our custom `profiler.py` script #17467 to run 5 iterations
measuring true disk-level cold starts (with `__pycache__` sweeps) on the
`google-cloud-compute` library. The results validate this Phase 1 PEP
810 Native Lazy Loading implementation:
### Python 3.14 (Current Eager Import)
* **Time (Median):** `23,246.97 ms` (~23.2 seconds)
* **Memory (Physical RSS):** `224.87 MB`
* **Code Volume:** Loaded `1,407` modules (`1,040,992` lines of code)
### Python 3.15.0b2 (Phase 1 PEP 810 Lazy Proxy)
* **Time (Median):** `1,062.87 ms` (~1.06 seconds)
* **Memory (Physical RSS):** `7.21 MB`
* **Code Volume:** Loaded `15` modules (`8,064` lines of code)
**Impact:** By natively deferring the 120+ submodules at the C-level, we
bypassed parsing over **1 million lines of code**. This resulted in an
**approximately 22x reduction in startup latency (~95% speedup)**, and a
staggering **96% reduction in peak RAM consumption** (dropping from
~225MB down to just ~7MB).
Related Links:
see #17594 for a demonstration of this generator change applied to
google-cloud-compute package.
Design Doc: go/sdk-performance-design
Towards googleapis/python-aiplatform#47491 parent 2ddcf4d commit 8a1270c
9 files changed
Lines changed: 135 additions & 0 deletions
File tree
- packages/gapic-generator
- gapic/templates/%namespace/%name_%version/%sub
- tests/integration/goldens
- asset/google/cloud/asset_v1
- credentials/google/iam/credentials_v1
- eventarc/google/cloud/eventarc_v1
- logging_internal/google/cloud/logging_v2
- logging/google/cloud/logging_v2
- redis_selective/google/cloud/redis_v1
- redis/google/cloud/redis_v1
- storagebatchoperations/google/cloud/storagebatchoperations_v1
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
15 | 37 | | |
16 | 38 | | |
17 | 39 | | |
| |||
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
25 | 38 | | |
26 | 39 | | |
27 | 40 | | |
| |||
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
25 | 37 | | |
26 | 38 | | |
27 | 39 | | |
| |||
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
25 | 47 | | |
26 | 48 | | |
27 | 49 | | |
| |||
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
25 | 41 | | |
26 | 42 | | |
27 | 43 | | |
| |||
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
25 | 41 | | |
26 | 42 | | |
27 | 43 | | |
| |||
Lines changed: 11 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
25 | 36 | | |
26 | 37 | | |
27 | 38 | | |
| |||
Lines changed: 11 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
25 | 36 | | |
26 | 37 | | |
27 | 38 | | |
| |||
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
25 | 37 | | |
26 | 38 | | |
27 | 39 | | |
| |||
0 commit comments