Skip to content

perf(bluecell): precompile rule patterns and conditions once - #21

Open
PurpleCHOIms wants to merge 2 commits into
mainfrom
perf/bluecell-rulematcher-precompile
Open

PurpleCHOIms wants to merge 2 commits into
mainfrom
perf/bluecell-rulematcher-precompile

Conversation

@PurpleCHOIms

Copy link
Copy Markdown
Member

What

RuleMatcher recompiled every regex (_compile_pattern) and re-parsed + eval'd every condition on each tap event. During active engagements the Blue Cell tap streams one event per sandbox/target log line, so this recompilation ran on the hot path at line rate.

This hoists both out of the per-event path:

  • Patterns compile once, memoized via lru_cache on _compile_pattern.
  • Conditions compile once into a reusable evaluator (_compile_condition), built at RuleMatcher construction. _evaluate_condition now delegates to it (single source of truth, no logic duplication).
  • match() performs no re.compile/eval in its hot loop.

Behavior

Unchanged. Public API (RuleMatcher, load_rules, DetectionRule/DetectionEvent, score_mttd) and match semantics are preserved — including re: regex vs. literal patterns, and/or/not/parentheses conditions, the empty-condition "all selections must match" rule, and the "unknown selection name → never fires" rule.

Tests

New tests/unit/bluecell/test_rule_match.py characterizes the matcher (single/multi selection, re: patterns, boolean conditions, empty + unknown-selection cases) and asserts the hot loop does zero compilation. Full packages/autobot/tests/unit/ suite passes (259 tests).

Performance

~2x on the 10-rule sample_rules.jsonl (measured, same machine: 40.6 → 20.5 µs/event over 20k events). The gain scales with rule count × patterns-per-rule, so larger Sigma-style rule packs benefit more.

Changelog

Recorded under Unreleased in CHAGELOG.md. No package version or release implied.

🤖 Generated with Claude Code

mschoi added 2 commits October 27, 2026 16:39
RuleMatcher recompiled every regex via _compile_pattern and re-parsed +
eval'd every condition on each tap event. Hoist both out of the
per-event path: patterns compile once (memoized _compile_pattern) and
conditions compile once into a reusable evaluator (_compile_condition),
built at RuleMatcher construction. match() does no re.compile/eval work
in its hot loop.

Behavior preserved (public API and match semantics unchanged); add
characterization tests covering single/multi selection, re: patterns,
and/or/not/parentheses, empty + unknown-selection conditions, and that
the hot loop performs zero compilation. ~2x on the 10-rule sample,
scaling with rule count x patterns-per-rule.

This branch has not been deployed

No deployments
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