Skip to content

_BookState.to_orderbook re-validates every level through Pydantic on each materialization #327

Closed

Description

@TexasCoding

Problem

_BookState.to_orderbook constructs 2 * N OrderbookLevel instances and one Orderbook instance via the full BaseModel.__init__ pipeline on every cache miss. DollarDecimal's BeforeValidator(_coerce_decimal) and FixedPointCount's validator re-run on values that are already Decimal, plus pydantic's per-field type check / extra-field collection runs for every level.

The _BookState.yes / .no dicts are an invariant of the manager — _apply_snapshot_inplace and _apply_delta_inplace only ever store Decimal values into them. The re-validation work is therefore pure overhead. With the #244 cache invalidated on every delta, the _OrderbookIterator hot path pays this on every frame; on a 200-level book that's 401 unnecessary model_validate invocations per delta.

Evidence

  • kalshi/ws/orderbook.py:55-73 — every cache miss goes through OrderbookLevel(price=..., quantity=...) and Orderbook(...)
def to_orderbook(self) -> Orderbook:
    if self._cached is not None:
        return self._cached
    yes_levels = [
        OrderbookLevel(price=price, quantity=qty) for price, qty in sorted(self.yes.items())
    ]
    no_levels = [
        OrderbookLevel(price=price, quantity=qty) for price, qty in sorted(self.no.items())
    ]
    ob = Orderbook(ticker=self.ticker, yes=yes_levels, no=no_levels)
    self._cached = ob
    return ob

Suggested fix

Replace the constructor calls with model_construct, which skips the validator pipeline:

yes_levels = [
    OrderbookLevel.model_construct(price=price, quantity=qty)
    for price, qty in sorted(self.yes.items())
]
no_levels = [
    OrderbookLevel.model_construct(price=price, quantity=qty)
    for price, qty in sorted(self.no.items())
]
ob = Orderbook.model_construct(ticker=self.ticker, yes=yes_levels, no=no_levels)

Inputs are already-typed Decimal from the manager's invariant, so skipping validation is safe. Document the invariant at the top of _BookState. Existing tests in tests/ws/test_orderbook.py cover the public Decimal-typed shape. scripts/bench_orderbook_iterator.py is the regression harness — expect a measurable reduction in per-delta materialization cost.

Source

Round-3 independent audit (reviewer: performance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance / hot-path concern

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions