Files
cleveragents-core/benchmarks/skill_registry_bench.py
T
2026-02-21 16:30:40 +00:00

128 lines
3.7 KiB
Python

"""ASV benchmarks for Skill Registry persistence operations.
Measures the performance of:
- SkillModel.from_domain() construction
- SkillModel.to_domain() reconstruction
- SkillRepository CRUD operations (in-memory SQLite)
- SkillRegistryService list operations
"""
from __future__ import annotations
import sys
import uuid
from pathlib import Path
try:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from cleveragents.domain.models.core.skill import Skill
from cleveragents.infrastructure.database.models import Base, SkillModel
from cleveragents.infrastructure.database.repositories import (
SkillRepository,
)
except ModuleNotFoundError:
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from cleveragents.domain.models.core.skill import Skill
from cleveragents.infrastructure.database.models import Base, SkillModel
from cleveragents.infrastructure.database.repositories import (
SkillRepository,
)
def _make_skill(name: str = "bench/skill-test") -> Skill:
"""Create a minimal Skill domain object for benchmarks."""
return Skill(
name=name,
description=f"Benchmark skill {name}",
tool_refs=["local/tool-a", "local/tool-b"],
)
class SkillModelConstruction:
"""Benchmark SkillModel.from_domain() construction."""
def setup(self) -> None:
self.skill = _make_skill()
def time_from_domain(self) -> None:
SkillModel.from_domain(self.skill)
class SkillModelReconstruction:
"""Benchmark SkillModel.to_domain() reconstruction."""
def setup(self) -> None:
self.model = SkillModel.from_domain(_make_skill())
def time_to_domain(self) -> None:
self.model.to_domain()
class SkillRepositoryCRUD:
"""Benchmark SkillRepository CRUD with in-memory SQLite."""
timeout = 60.0
def setup(self) -> None:
self.engine = create_engine("sqlite:///:memory:", echo=False)
Base.metadata.create_all(self.engine)
self.factory = sessionmaker(bind=self.engine)
self.repo = SkillRepository(session_factory=self.factory)
def teardown(self) -> None:
self.engine.dispose()
def time_create_skill(self) -> None:
skill = _make_skill(f"bench/{uuid.uuid4().hex[:8]}")
self.repo.create(skill)
# Commit via the same session-factory the repo uses internally
session = self.factory()
try:
session.commit()
finally:
session.close()
def time_get_skill(self) -> None:
self.repo.get_by_name("bench/nonexistent")
def time_list_all(self) -> None:
self.repo.list_all()
def time_list_namespace(self) -> None:
self.repo.list_all(namespace="bench")
class SkillRegistryListPerformance:
"""Benchmark listing performance with many skills."""
timeout = 120.0
def setup(self) -> None:
self.engine = create_engine("sqlite:///:memory:", echo=False)
Base.metadata.create_all(self.engine)
self.factory = sessionmaker(bind=self.engine)
self.repo = SkillRepository(session_factory=self.factory)
# Insert 100 skills and commit via the same session-factory
for i in range(100):
skill = _make_skill(f"bench/skill-{i:04d}")
self.repo.create(skill)
session = self.factory()
try:
session.commit()
finally:
session.close()
def teardown(self) -> None:
self.engine.dispose()
def time_list_100_skills(self) -> None:
self.repo.list_all()
def time_list_100_skills_filtered(self) -> None:
self.repo.list_all(namespace="bench")