Skip to content

P2: Fix performance bottlenecks in scan/review pipeline #335

Description

@ajianaz

Summary

Cora scan found 10 performance issues, all sharing the same pattern: repeated expensive operations inside loops that should be done once.

Issues

Regex recompiled per line (#41src/engine/rules/matching.rs:36)

Regex::new(&rule.pattern) called for every line of every rule. Should precompile once when loading rules.

Fix: Store compiled regex alongside each rule, compile once at load time.

Per-file DB queries in nested loops (#5src/mcp/tools.rs:528)

handle_find_affected_tests runs SQL per file → per symbol → per test pattern. Classic N+1 query pattern.

Fix: Batch lookups, prepare statements once, deduplicate before traversal.

Affected test analysis repeated graph lookups (#13src/main.rs:844)

Same N+1 pattern in the Affected command — queries symbols per file, callers per symbol.

Fix: Fetch all symbols for all files in one query, resolve callers in fewer set-based queries.

Prepared statement recreated in inner loop (#14src/main.rs:888)

conn.prepare(...) called inside test-pattern loop for every changed file.

Fix: Prepare once before loop, reuse statement.

Secrets scanner no early cutoff (#59src/engine/secrets_scanner.rs:137)

Scans all files/hunks/lines even after max_findings reached. Capped only after full scan.

Fix: Check findings.len() >= max_findings during scan and break early.

Symbol cap does not stop file scanning (#70src/engine/context/extraction.rs:281)

break exits only inner symbol loop, not the line iteration loop.

Fix: Add labeled break or guard before line extraction.

Repeated file reads during sibling search (#67 — `src/engine/context/resolver.rs:447)

resolve_function and resolve_type read same files from disk repeatedly.

Fix: Introduce file-content cache keyed by path for duration of context build.

New Tokio runtime per MCP tool call (#3src/mcp/tools.rs:643)

handle_review_diff creates fresh tokio::runtime::Runtime for every request.

Fix: Create and reuse single runtime for server lifetime.

Regex recompiled per line in detect_function_entry (#22src/index/extract.rs:423)

Creates new Regex instances per call. Module already uses LazyLock statics.

Fix: Move to static LazyLock<Regex> values.

Per-file transaction for prune_deleted (#24src/index/mod.rs:249)

Starts/commits separate transaction per deleted file.

Fix: Open one transaction before loop, commit once at end.

Effort estimate: 1-2 days

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions