-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
179 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
"""Models based on https://github.com/tortoise/orm-benchmarks""" | ||
|
||
from datetime import datetime | ||
from decimal import Decimal | ||
from random import choice | ||
from typing import Iterator, Literal, Optional, get_args | ||
|
||
from odmantic import Field, Model | ||
|
||
Level = Literal[10, 20, 30, 40, 50] | ||
VALID_LEVELS = list(get_args(Level)) | ||
|
||
|
||
class SmallJournal(Model): | ||
timestamp: datetime = Field(default_factory=datetime.utcnow) | ||
level: Level = Field(index=True) | ||
text: str = Field(index=True) | ||
|
||
@classmethod | ||
def get_random_instances(cls, context: str, count: int) -> Iterator["SmallJournal"]: | ||
for i in range(count): | ||
yield cls(level=choice(VALID_LEVELS), text=f"From {context}, item {i}") | ||
|
||
|
||
class JournalWithRelations(Model): | ||
timestamp: datetime = Field(default_factory=datetime.utcnow) | ||
level: Level = Field(index=True) | ||
text: str = Field(index=True) | ||
|
||
# parent | ||
|
||
|
||
class BigJournal(Model): | ||
timestamp: datetime = Field(default_factory=datetime.utcnow) | ||
level: Level = Field(index=True) | ||
text: str = Field(index=True) | ||
|
||
col_float1: float = Field(default=2.2) | ||
col_smallint1: int = Field(default=2) | ||
col_int1: int = Field(default=2000000) | ||
col_bigint1: int = Field(default=99999999) | ||
col_char1: str = Field(default=255, max_length=255) | ||
col_text1: str = Field( | ||
default="Moo,Foo,Baa,Waa,Moo,Foo,Baa,Waa,Moo,Foo,Baa,Waa", | ||
) | ||
col_decimal1: Decimal = Field(default=Decimal("2.2")) | ||
col_json1: dict = Field( | ||
default={"a": 1, "b": "b", "c": [2], "d": {"e": 3}, "f": True}, | ||
) | ||
|
||
col_float2: Optional[float] = Field(default=None) | ||
col_smallint2: Optional[int] = Field(default=None) | ||
col_int2: Optional[int] = Field(default=None) | ||
col_bigint2: Optional[int] = Field(default=None) | ||
col_char2: Optional[str] = Field(default=None, max_length=255) | ||
col_text2: Optional[str] = Field( | ||
default=None, | ||
) | ||
col_decimal2: Optional[Decimal] = Field(default=None) | ||
col_json2: Optional[dict] = Field( | ||
default=None, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from contextlib import nullcontext | ||
|
||
import pytest | ||
from pytest_codspeed import BenchmarkFixture | ||
|
||
from odmantic import AIOEngine, SyncEngine | ||
|
||
from .models import VALID_LEVELS, SmallJournal | ||
|
||
pytestmark = pytest.mark.asyncio | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
async def test_insert_small_single( | ||
benchmark, aio_engine: AIOEngine, count: int, use_session: bool | ||
): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
|
||
@benchmark | ||
async def _(): | ||
async with aio_engine.session() as session: | ||
for instance in instances: | ||
await session.save(instance) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from contextlib import nullcontext | ||
|
||
import pytest | ||
from pytest_codspeed import BenchmarkFixture | ||
|
||
from odmantic import AIOEngine, SyncEngine | ||
|
||
from .models import VALID_LEVELS, SmallJournal | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
@pytest.mark.parametrize( | ||
"use_session", [pytest.param(True, id="session"), pytest.param(False, id="direct")] | ||
) | ||
def test_insert_small_single( | ||
benchmark, aio_engine: AIOEngine, count: int, use_session: bool | ||
): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
|
||
@benchmark | ||
async def _(): | ||
with aio_engine.session() if use_session else nullcontext(aio_engine) as engine: | ||
for instance in instances: | ||
engine.save(instance) | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
@pytest.mark.parametrize( | ||
"use_session", [pytest.param(True, id="session"), pytest.param(False, id="direct")] | ||
) | ||
def test_write_small_bulk( | ||
benchmark, sync_engine: SyncEngine, count: int, use_session: bool | ||
): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
|
||
@benchmark | ||
def _(): | ||
with sync_engine.session() if use_session else nullcontext( | ||
sync_engine | ||
) as engine: | ||
engine.save_all(instances) | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
def test_filter_by_level_small(benchmark, sync_engine: SyncEngine, count: int): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
sync_engine.save_all(instances) | ||
|
||
@benchmark | ||
def _(): | ||
total = 0 | ||
for level in VALID_LEVELS: | ||
total += len( | ||
list(sync_engine.find(SmallJournal, SmallJournal.level == level)) | ||
) | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
def test_filter_limit_skip_by_level_small( | ||
benchmark, sync_engine: SyncEngine, count: int | ||
): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
sync_engine.save_all(instances) | ||
|
||
@benchmark | ||
def _(): | ||
total = 0 | ||
for level in VALID_LEVELS: | ||
total += len( | ||
list( | ||
sync_engine.find( | ||
SmallJournal, SmallJournal.level == level, limit=20, skip=20 | ||
) | ||
) | ||
) | ||
|
||
|
||
@pytest.mark.parametrize("count", [10, 50, 100]) | ||
def test_find_one_by_id(benchmark, sync_engine: SyncEngine, count: int): | ||
instances = list(SmallJournal.get_random_instances("test_write_small", count)) | ||
sync_engine.save_all(instances) | ||
ids = [instance.id for instance in instances] | ||
|
||
@benchmark | ||
def _(): | ||
for id_ in ids: | ||
sync_engine.find_one(SmallJournal, SmallJournal.id == id_) |