Skip to content

perf: Map identity overrides, evaluate environment flags once per document refresh - #262

Merged
khvn26 merged 14 commits into
mainfrom
perf/local-eval-regression
Oct 21, 2026
Merged

khvn26 merged 14 commits into
mainfrom
perf/local-eval-regression

Conversation

@khvn26

@khvn26 khvn26 commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Contributes to #198.

In this PR, we resolve two performance regressions in local evaluation mode, both dating from the move to the evaluation context engine (4.0.0/5.0.0).

  1. Identity overrides are mapped to segments, one per unique set of overrides, and every one of them was matched on every identity evaluation. They're now indexed by identifier once per environment document refresh, and each evaluation only includes the requested identity's own segment. This decouples local evaluation runtime from the number of identity overrides.
  2. Environment flags were evaluated by the engine on every get_environment_flags() call, although they only depend on the environment document. They're now evaluated once per environment document refresh.

Evaluation state now lives in a new LocalEvaluation object, rebuilt on every environment document refresh.

Environment flags and single identity flags are now well ahead of 3.8.0.

An all_flags() call for an identity is still 7–18% slower than 3.8.0; the remaining gap will be closed engine-side.

Benchmark: gist

Identity overrides segments are indexed by identifier, and each identity
is evaluated with its own only, narrowed to its identifier. Evaluation
cost no longer grows with the number of identity overrides.

Environment flags are evaluated once per environment document.

Refs #198
@khvn26
khvn26 requested a review from a team as a code owner October 16, 2026 17:40
@khvn26
khvn26 requested review from emyller and removed request for a team October 16, 2026 17:40
`SegmentOverridesIndex` is now the read-only mapping consumers take, so
`SegmentOverridesMapping` goes. Indexes are built as dicts of a new
`SegmentContexts` alias, which also shortens repeated annotations.
One type for every index, built or read: `dict` and the per-identity
`ChainMap` are both mutable mappings.
@khvn26
khvn26 marked this pull request as ready for review October 19, 2026 11:06
@khvn26 khvn26 changed the title perf: Fix local evaluation regressions perf: Map identity overrides, evaluate environment flags once per document refresh Oct 19, 2026

@emyller emyller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks solid in its logic. Left a few comments that aim to contribute to interface and sticking to testing patterns.

I'd also advise against using base to name anything. It does not add meaning.

Comment thread flagsmith/flagsmith.py Outdated
Comment thread flagsmith/flagsmith.py Outdated
Comment thread flagsmith/mappers.py Outdated
Comment thread flagsmith/mappers.py Outdated
Comment thread flagsmith/models.py Outdated
Comment thread tests/test_flagsmith.py Outdated
Comment thread tests/test_local_evaluation.py Outdated
Comment thread tests/test_local_evaluation.py Outdated
The client kept the evaluation context next to the `LocalEvaluation` built
from it. It now keeps the `LocalEvaluation` only, whose `context` is the
context without identity overrides segments, formerly `base_context`.
Identity overrides segments are kept apart, by key.

Also drops name mangling, as `__evaluation_context` goes.
`map_identifiers_to_identity_overrides_rules` built a single rule, so it
is now `map_identifiers_to_identity_overrides_rule`, returning that rule.
Identity overrides conditions are typed as `InOperatorSegmentCondition`
where they are built, and identifiers are read back as such, rather than
cast to a list of strings with a comment.
Replaces comments explaining what the keys are.
Also drops `base` from test and variable names.
@khvn26
khvn26 force-pushed the perf/local-eval-regression branch from 3e37352 to 8fd7a17 Compare October 20, 2026 14:39
Identity overrides were mapped to segments, one per unique set of
overrides, merged into the evaluation context, then picked back out of it
by `LocalEvaluation` and narrowed to an identity on every evaluation.

They are now mapped straight from the environment document to a segment
per identifier, kept out of the evaluation context. `LocalEvaluation`
indexes each one's overrides once per environment document, so an
identity evaluation only adds its own segment.
Drops comments, shortens the `LocalEvaluation` docstring, and specs the
`LocalEvaluation` mocks in streaming manager tests.
@khvn26

khvn26 commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

Updated the logic to map env doc's identity_overrides straight into the new cache.

@khvn26
khvn26 requested a review from emyller October 20, 2026 16:07
@khvn26
khvn26 merged commit 4fafcd9 into main Oct 21, 2026
5 checks passed
@khvn26
khvn26 deleted the perf/local-eval-regression branch October 21, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants