Skip to content

Python driver benchmarks - #55

Open
patrycja-ziemkiewicz wants to merge 19 commits into
scylladb:mainfrom
patrycja-ziemkiewicz:python-driver-benchmarks
Open

patrycja-ziemkiewicz wants to merge 19 commits into
scylladb:mainfrom
patrycja-ziemkiewicz:python-driver-benchmarks

Conversation

@patrycja-ziemkiewicz

@patrycja-ziemkiewicz patrycja-ziemkiewicz commented Mar 17, 2026

Copy link
Copy Markdown
Collaborator

This PR add benchmark scenarios for the python-rs driver

Example plots generated by the benchmarker:
image
image

@patrycja-ziemkiewicz
patrycja-ziemkiewicz force-pushed the python-driver-benchmarks branch 2 times, most recently from 01c17af to 09080d8 Compare March 19, 2026 14:56
adespawn added a commit to adespawn/scylla-rust-driver that referenced this pull request Mar 19, 2026
When creating nodejs-rs driver, we have created a set of benchmarks,
that we have used to compare the performance of the nodejs-rs driver with
the node.js cassandra-driver and the scylla rust driver. This meant,
that we had some benchmark code for rust driver inside nodejs driver repository.

With two other wrappers creating benchmarks*, that are heavily based,
on the benchmarks from nodejs ZPP, we have decided with @wprzytula
to move the code for the rust part of the benchmarks to the rust driver
repository, so that it can be used by all three wrappers and maintained in one place.

* C# driver: scylladb/csharp-rs-driver#100
* Python driver: scylladb/python-rs-driver#55
adespawn added a commit to adespawn/scylla-rust-driver that referenced this pull request Mar 19, 2026
When creating nodejs-rs driver, we have created a set of benchmarks,
that we have used to compare the performance of the nodejs-rs driver with
the node.js cassandra-driver and the scylla rust driver. This meant,
that we had some benchmark code for rust driver inside nodejs driver repository.

With two other wrappers creating benchmarks*, that are heavily based,
on the benchmarks from nodejs ZPP, we have decided with @wprzytula
to move the code for the rust part of the benchmarks to the rust driver
repository, so that it can be used by all three wrappers and maintained in one place.

* C# driver: scylladb/csharp-rs-driver#100
* Python driver: scylladb/python-rs-driver#55
@patrycja-ziemkiewicz
patrycja-ziemkiewicz force-pushed the python-driver-benchmarks branch 5 times, most recently from 1415afb to c254469 Compare March 24, 2026 12:25
@patrycja-ziemkiewicz
patrycja-ziemkiewicz force-pushed the python-driver-benchmarks branch 2 times, most recently from b326ab3 to 62e4c14 Compare April 30, 2026 13:38
@patrycja-ziemkiewicz
patrycja-ziemkiewicz marked this pull request as ready for review April 30, 2026 14:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an SDB (ScyllaDB Drivers Benchmarker) benchmark suite for the Python-RS driver, including single-threaded and concurrent scenarios plus documentation/config to run and plot results.

Changes:

  • Introduces benchmark scenario scripts for insert, select (small/large), (de)serialization, batch, and paging.
  • Adds concurrent variants of key scenarios (insert/select/(de)serialization/paging).
  • Adds SDB configuration (config.yml) and a README with instructions for running/plotting.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
benchmark/common.py Shared DB setup/teardown helpers and data generators for all benchmark scenarios.
benchmark/insert.py Insert throughput benchmark using prepared statements.
benchmark/ser.py Serialization-focused benchmark inserting complex rows.
benchmark/deser.py Deserialization-focused benchmark selecting complex rows.
benchmark/batch.py Batch execution benchmark using logged batches.
benchmark/paging.py Manual paging benchmark using iter_current_page() + fetch_next_page().
benchmark/select_runner.py Shared select benchmark runner used by small/large select wrappers.
benchmark/small_select.py Wrapper to run select benchmark with a small row count.
benchmark/large_select.py Wrapper to run select benchmark with a large row count.
benchmark/concurrent_insert.py Concurrent insert benchmark using asyncio tasks.
benchmark/concurrent_select.py Concurrent select benchmark using asyncio tasks.
benchmark/concurrent_ser.py Concurrent serialization benchmark using asyncio tasks.
benchmark/concurrent_deser.py Concurrent deserialization benchmark using asyncio tasks.
benchmark/concurrent_paging.py Concurrent paging benchmark using asyncio tasks.
benchmark/config.yml SDB benchmark definitions and backend run commands for this repo.
benchmark/README.md Instructions for building SDB, running benchmarks, and plotting results.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread benchmark/config.yml Outdated
Comment thread benchmark/README.md Outdated
Comment thread benchmark/select_runner.py Outdated
Comment thread benchmark/deser.py Outdated
Comment thread benchmark/select_runner.py Outdated
Comment thread benchmark/README.md Outdated
Comment thread benchmark/concurrent_select.py Outdated
Comment thread benchmark/concurrent_deser.py Outdated
Comment thread benchmark/common.py Outdated
Comment thread benchmark/common.py Outdated
Comment thread benchmark/common.py Outdated
Comment thread benchmark/common.py
Comment thread benchmark/common.py Outdated
Comment thread benchmark/common.py Outdated
Comment thread benchmark/concurrent_insert.py Outdated
Comment thread benchmark/concurrent_ser.py Outdated
Copilot AI review requested due to automatic review settings May 7, 2026 10:54
Copilot AI review requested due to automatic review settings May 16, 2026 22:03


async def test(session: Session, cnt: int, num_of_rows: int):
prepared = await session.prepare(SIMPLE_SELECT_QUERY)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency prepare outside test(), same in complex

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 34 changed files in this pull request and generated 10 comments.

Comment thread pyproject.toml
Comment on lines +10 to +12
dependencies = [
"scylla-driver>=3.29.10",
]
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=get_simple_data(),
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=get_simple_data(),
Comment on lines +12 to +24
async def test(session: Session, prepared: PreparedStatement, cnt: int, num_of_rows: int):
for _ in range(cnt):
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=None,
paging_state=None,
)
)
result = await fut
assert len(result) == num_of_rows # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]


Comment on lines +12 to +24
async def test(session: Session, prepared: PreparedStatement, cnt: int, num_of_rows: int):
for _ in range(cnt):
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=None,
paging_state=None,
)
)
result = await fut
assert len(result) == num_of_rows # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]


Comment on lines +2 to +10
import sys

from common import (
SIMPLE_SELECT_QUERY,
)
from python_rs_helpers import connect
from scylla.session import Session


Comment on lines +2 to +11
import sys

from cassandra.cluster import Session # pyright: ignore[reportMissingTypeStubs]
from cassandra.query import PreparedStatement # pyright: ignore[reportMissingTypeStubs]
from common import (
SIMPLE_SELECT_QUERY,
)
from python_helpers import PAGE_SIZE, connect, to_asyncio


Comment on lines +4 to +8
from common import (
SIMPLE_INSERT_QUERY,
get_simple_data,
)
from python_rs_helpers import init_simple_table, init_with_inserts
from scylla.session import Session
from scylla.statement import PreparedStatement, Statement

STEP = 3971
)
from python_helpers import connect, to_asyncio

STEP = 3971
Copilot AI review requested due to automatic review settings July 9, 2026 14:40
@patrycja-ziemkiewicz
patrycja-ziemkiewicz force-pushed the python-driver-benchmarks branch 2 times, most recently from 6231818 to 0b157a1 Compare July 9, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 34 changed files in this pull request and generated 5 comments.

Comment thread pyproject.toml
Comment on lines 9 to +12
dynamic = ["version"]
dependencies = [
"scylla-driver>=3.29.10",
]
Comment thread benchmark/README.md
Comment on lines +77 to +81
sdb -d test.db plot \
-b config.yml \
-o concurrent-result.png \
--series Python-RS-concurrent/ \
series
Comment on lines +55 to +57
tasks = [session.execute(prepared, get_data(), paged=False) for _ in range(num_of_rows)]

await asyncio.gather(*tasks)
Comment on lines +12 to +23
async def test(session: Session, prepared: PreparedStatement, cnt: int, num_of_rows: int):
for _ in range(cnt):
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=None,
paging_state=None,
)
)
result = await fut
assert len(result) == num_of_rows # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]

Comment on lines +12 to +23
async def test(session: Session, prepared: PreparedStatement, cnt: int, num_of_rows: int):
for _ in range(cnt):
fut = to_asyncio(
session.execute_async( # pyright: ignore[reportUnknownMemberType]
query=prepared,
parameters=None,
paging_state=None,
)
)
result = await fut
assert len(result) == num_of_rows # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]

patrycja-ziemkiewicz and others added 19 commits July 9, 2026 18:09
To accurately compare old Python driver to Python-Rs driver we will
interact with the old driver exclusively in an asynchronous manner using
asyncio.

For that we need to translate `ResponseFuture` callbacks to asyncio
future. This translation approach is sensible and provides at least
somewhat usable interface for interaction with Python driver with
minimal overhead required to make sure scheduled `RequestFuture` runs to
completion.
footnote:
To be consistent with asyncio usage (and actual asynchronous execution
instead of awaitng immidiately in "concurrent" test scenarios) we are
intentionally not using the blocking `.result()` but the asyncio
compatible awaitable protocol with `to_asyncio()`.

@wprzytula wprzytula left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, you want to merge this for more convenient work with benchmarks, until the benchmarker is improved.

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.

5 participants