Thanks to visit codestin.com
Credit goes to GitHub.com

Skip to content

Conversation

@franciscojavierarceo
Copy link
Member

@franciscojavierarceo franciscojavierarceo commented Jan 30, 2026

Implement performance optimizations for FeatureStore:

  • Lazy Initialization: Convert registry, provider, and OpenLineage emitter
    to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

  • Feature Service Caching: Add caching layer for feature service resolution.
    Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 [email protected]


Open with Devin

franciscojavierarceo and others added 2 commits January 29, 2026 23:31
Implement performance optimizations for FeatureStore:

- **Lazy Initialization**: Convert registry, provider, and OpenLineage emitter
  to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

- **Feature Service Caching**: Add caching layer for feature service resolution.
  Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 <[email protected]>
@franciscojavierarceo franciscojavierarceo requested a review from a team as a code owner January 30, 2026 05:00
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issues and 5 additional flags in Devin Review.

Open in Devin Review

When refresh_registry() or plan() methods refresh the registry, the feature
service cache must be cleared to avoid serving stale cached results.

- Add _clear_feature_service_cache() helper method
- Clear cache in refresh_registry() and plan() methods
- Prevents data consistency issues with cached feature services
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issue and 6 additional flags in Devin Review.

Open in Devin Review

Fixes AttributeError where tests were directly accessing _registry before
lazy initialization. With lazy loading, _registry starts as None and must
be accessed through the registry property to trigger initialization.

- Replace ._registry. with .registry. in test files
- Add runtime error check in registry property for failed initialization
- Ensures backward compatibility with existing code patterns

Fixes CI test failures in search API tests.
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issue and 8 additional flags in Devin Review.

Open in Devin Review

The __repr__ method was accidentally calling self.registry (property) instead of
self._registry (attribute), which would trigger lazy initialization whenever
the FeatureStore object was printed or logged.

This completely defeated the lazy loading optimization since any debugging,
logging, or repr() call would cause full initialization (negating the 2.4s
to 0.5s performance gain).

- Change self.registry to self._registry in __repr__ method
- Preserves lazy loading benefits for debugging/logging scenarios
- Maintains correct status reporting without side effects
@franciscojavierarceo franciscojavierarceo merged commit b37b7d0 into master Jan 30, 2026
22 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants