Skip to content

Add holistic table event processing benchmark - #7061

Open
FarhanAliRaza wants to merge 2 commits into
reflex-dev:mainfrom
FarhanAliRaza:benchmark/holistic-table-events
Open

Add holistic table event processing benchmark#7061
FarhanAliRaza wants to merge 2 commits into
reflex-dev:mainfrom
FarhanAliRaza:benchmark/holistic-table-events

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Add an order-management workload to measure backend event performance beyond counter increments. Six events filter and sort 1,000 dataclass rows, recompute totals, generate deltas, and serialize StateUpdate envelopes through Reflex's JSON encoder.

The benchmark warms state before timing and returns to the same filter and sort direction after each sample. A separate correctness test verifies serialized rows and totals across repeated batches. The README documents how to run it and the measurement boundary: processor lifecycle is included; hydration, network transport, database access, and browser rendering are excluded.

Related to #7056, which includes the original benchmark alongside runtime optimizations. This PR isolates the benchmark and adds repeatable samples, correctness assertions, and run documentation. Encoding is measured through json_dumps; changes confined to Socket.IO's encoder configuration require updating the benchmark's encoder too.

Validation

  • Event tests: 3 passed.
  • CodSpeed mode: 2 benchmarks passed, correctness test deselected.
  • Commit hooks: Ruff formatting/checks, codespell, stub update, Pyright, and ty passed.
  • Full uv run pyright reflex tests: passed.
  • git diff --check: passed.

Repository-wide Ruff checks report unrelated existing issues under .states.bak/ and ignore/. The full unit suite was not run; this change only adds benchmark coverage and documentation.

No package source or public behavior changes; no changelog fragment included.

Review in cubic

@FarhanAliRaza
FarhanAliRaza requested a review from a team as a code owner September 7, 2026 17:56
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

The benchmark coverage improvement is useful, but the explicit repository requirement concerning hardcoded identifier keys remains unresolved and must be satisfied before merging.

Findings

  1. P2 Table Correctness Is Unchecked

Summary

  • Adds table filtering, sorting, computed totals, and JSON encoding to the measured pipeline.
  • Warms table state before timing and documents the benchmark boundary.
  • Refactors the benchmark harness, but removes the separate serialized-delta correctness assertions.

Comment on lines +230 to +233
{
"name": f"order {i}",
"customer": f"customer {i % 50}",
"amount": i * 1.5,

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.

P2 Hardcoded State Field Keys

These assertions use "status", "sort_reverse", "filtered_orders", and "total_amount" directly as dictionary keys. This violates the repository directive that string literals used as identifiers or keys must be extracted into named constants, and it can let the assertions drift if the state fields are renamed. This repository requirement must be satisfied before merging.

Rule Used: String literals that are used as identifiers or ke... (source)

Learned From
reflex-dev/flexgen#2170

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codspeed-hq

codspeed-hq Bot commented Sep 7, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 3.03%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 38 untouched benchmarks
🆕 2 new benchmarks
⏩ 9 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
test_var_access[mutable_dict] 47 ms 45.6 ms +3.03%
🆕 test_process_event[counter] N/A 11.4 ms N/A
🆕 test_process_event[table] N/A 694.1 ms N/A

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing FarhanAliRaza:benchmark/holistic-table-events (8dedc2d) with main (5d9724e)

Open in CodSpeed

Footnotes

  1. 9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread tests/benchmarks/test_event_processing.py Outdated
await p.enqueue(token, event) for _ in range(num_events)
await p.enqueue("benchmark-token", event) for event in events
]):
pass

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.

P2 Table Correctness Is Unchecked

The refactor removes test_table_event_deltas, while run_events now checks only how many updates were emitted. The serialized table updates are discarded without validating their contents, so a regression that omits or corrupts the filtered rows, sort direction, or computed total could still pass and appear as a performance improvement. Please retain a separate correctness test for the serialized table deltas.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@cubic-dev-ai cubic-dev-ai Bot 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.

2 issues found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/benchmarks/test_event_processing.py">

<violation number="1" location="tests/benchmarks/test_event_processing.py:39">
P2: The counter workload's state grows across benchmark samples: each batch runs three `increment` events and never restores state, so `counter` rises by 3 per invocation. Because `elements`, `nested_elements`, `show_odd`, and `show_even` are computed vars depending on `counter`, every subsequent sample recomputes and serializes strictly larger structures, so the measured cost is not constant. This contradicts the PR's stated goal of repeatable samples (the table workload restores via an even number of sort-reversal toggles; the counter workload has no restore). CodSpeed aggregates multiple invocations, so results mix an increasing workload and are not reproducible. Reset `counter` (or re-run from a fixed state) at the end of each sample so every benchmark invocation measures the same work.</violation>

<violation number="2" location="tests/benchmarks/test_event_processing.py:60">
P2: Keep a separate correctness assertion for the serialized table updates instead of discarding the encoded result here. Counting emitted deltas will not detect missing or corrupted filtered rows, sort direction, or computed totals.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

if table
else BenchmarkState.event_handlers["increment"]
)
payloads = (

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.

P2: The counter workload's state grows across benchmark samples: each batch runs three increment events and never restores state, so counter rises by 3 per invocation. Because elements, nested_elements, show_odd, and show_even are computed vars depending on counter, every subsequent sample recomputes and serializes strictly larger structures, so the measured cost is not constant. This contradicts the PR's stated goal of repeatable samples (the table workload restores via an even number of sort-reversal toggles; the counter workload has no restore). CodSpeed aggregates multiple invocations, so results mix an increasing workload and are not reproducible. Reset counter (or re-run from a fixed state) at the end of each sample so every benchmark invocation measures the same work.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/benchmarks/test_event_processing.py, line 39:

<comment>The counter workload's state grows across benchmark samples: each batch runs three `increment` events and never restores state, so `counter` rises by 3 per invocation. Because `elements`, `nested_elements`, `show_odd`, and `show_even` are computed vars depending on `counter`, every subsequent sample recomputes and serializes strictly larger structures, so the measured cost is not constant. This contradicts the PR's stated goal of repeatable samples (the table workload restores via an even number of sort-reversal toggles; the counter workload has no restore). CodSpeed aggregates multiple invocations, so results mix an increasing workload and are not reproducible. Reset `counter` (or re-run from a fixed state) at the end of each sample so every benchmark invocation measures the same work.</comment>

<file context>
@@ -28,34 +19,45 @@
+        if table
+        else BenchmarkState.event_handlers["increment"]
+    )
+    payloads = (
+        [{"status": status} for status in ("open", "", "paid") * 2]
+        if table
</file context>

nonlocal emitted
emitted += 1
if table:
json_dumps(StateUpdate(delta=delta), separators=(",", ":"))

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.

P2: Keep a separate correctness assertion for the serialized table updates instead of discarding the encoded result here. Counting emitted deltas will not detect missing or corrupted filtered rows, sort direction, or computed totals.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/benchmarks/test_event_processing.py, line 60:

<comment>Keep a separate correctness assertion for the serialized table updates instead of discarding the encoded result here. Counting emitted deltas will not detect missing or corrupted filtered rows, sort direction, or computed totals.</comment>

<file context>
@@ -28,34 +19,45 @@
         emitted += 1
-        on_delta(delta)
+        if table:
+            json_dumps(StateUpdate(delta=delta), separators=(",", ":"))
 
     async def emit_event_impl(token: str, *events: Event) -> None:
</file context>

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.

1 participant