170 lines
4.8 KiB
Python
170 lines
4.8 KiB
Python
"""ASV benchmarks for DecisionService recording throughput.
|
|
|
|
Measures record_decision, list_decisions, get_tree, and snapshot operations.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from cleveragents.application.services.decision_service import (
|
|
DecisionService,
|
|
SnapshotStore,
|
|
)
|
|
from cleveragents.domain.models.core.decision import (
|
|
ContextSnapshot,
|
|
DecisionType,
|
|
)
|
|
except ModuleNotFoundError:
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
from cleveragents.application.services.decision_service import (
|
|
DecisionService,
|
|
SnapshotStore,
|
|
)
|
|
from cleveragents.domain.models.core.decision import (
|
|
ContextSnapshot,
|
|
DecisionType,
|
|
)
|
|
|
|
|
|
_PLAN_ID = "01HV00000000000000BENCH002"
|
|
|
|
|
|
class TimeRecordDecision:
|
|
"""Benchmark decision recording throughput."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self):
|
|
self.svc = DecisionService()
|
|
self._plan_counter = 0
|
|
|
|
def time_record_single(self):
|
|
self._plan_counter += 1
|
|
plan_id = f"01HV00000000000000BN{self._plan_counter:06d}"
|
|
self.svc.record_decision(
|
|
plan_id=plan_id,
|
|
decision_type=DecisionType.STRATEGY_CHOICE,
|
|
question="Benchmark question",
|
|
chosen_option="Benchmark choice",
|
|
)
|
|
|
|
|
|
class TimeRecordBatch:
|
|
"""Benchmark recording 50 decisions for one plan."""
|
|
|
|
timeout = 60
|
|
|
|
def time_record_50(self):
|
|
svc = DecisionService()
|
|
root = svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.PROMPT_DEFINITION,
|
|
question="Root",
|
|
chosen_option="Root choice",
|
|
)
|
|
for _ in range(49):
|
|
svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.STRATEGY_CHOICE,
|
|
question="Child",
|
|
chosen_option="Child choice",
|
|
parent_decision_id=root.decision_id,
|
|
)
|
|
|
|
|
|
class TimeListDecisions:
|
|
"""Benchmark list_decisions with 50 pre-seeded decisions."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self):
|
|
self.svc = DecisionService()
|
|
root = self.svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.PROMPT_DEFINITION,
|
|
question="Root",
|
|
chosen_option="Root choice",
|
|
)
|
|
for _ in range(49):
|
|
self.svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.STRATEGY_CHOICE,
|
|
question="Child",
|
|
chosen_option="Child choice",
|
|
parent_decision_id=root.decision_id,
|
|
)
|
|
|
|
def time_list_all(self):
|
|
self.svc.list_decisions(_PLAN_ID)
|
|
|
|
def time_list_by_type(self):
|
|
self.svc.list_by_type(_PLAN_ID, DecisionType.STRATEGY_CHOICE)
|
|
|
|
|
|
class TimeGetTree:
|
|
"""Benchmark get_tree with a 3-level tree (1 + 3 + 6 = 10 nodes)."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self):
|
|
self.svc = DecisionService()
|
|
root = self.svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.PROMPT_DEFINITION,
|
|
question="Root",
|
|
chosen_option="Root choice",
|
|
)
|
|
for _ in range(3):
|
|
child = self.svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.STRATEGY_CHOICE,
|
|
question="Child",
|
|
chosen_option="Child choice",
|
|
parent_decision_id=root.decision_id,
|
|
)
|
|
for _ in range(2):
|
|
self.svc.record_decision(
|
|
plan_id=_PLAN_ID,
|
|
decision_type=DecisionType.IMPLEMENTATION_CHOICE,
|
|
question="Grandchild",
|
|
chosen_option="GC choice",
|
|
parent_decision_id=child.decision_id,
|
|
)
|
|
|
|
def time_get_tree(self):
|
|
self.svc.get_tree(_PLAN_ID)
|
|
|
|
|
|
class TimeSnapshotStore:
|
|
"""Benchmark SnapshotStore operations."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self):
|
|
self.store = SnapshotStore()
|
|
self._counter = 0
|
|
# Pre-seed 100 snapshots
|
|
for i in range(100):
|
|
snap = ContextSnapshot(
|
|
hot_context_hash=f"sha256:bench{i:04d}",
|
|
hot_context_ref=f"ref-{i}",
|
|
)
|
|
self.store.store(f"DEC_{i:06d}", snap)
|
|
|
|
def time_store_snapshot(self):
|
|
self._counter += 1
|
|
snap = ContextSnapshot(
|
|
hot_context_hash=f"sha256:new{self._counter:06d}",
|
|
hot_context_ref=f"ref-new-{self._counter}",
|
|
)
|
|
self.store.store(f"NEW_{self._counter:06d}", snap)
|
|
|
|
def time_get_by_hash(self):
|
|
self.store.get_by_hash("sha256:bench0050")
|
|
|
|
def time_get_snapshot(self):
|
|
self.store.get("DEC_000050")
|