Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
run: |
uv venv
uv pip install dist/*.whl --group test
uv run --no-project pytest tests
uv run --no-project pytest tests -m "not perf"

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand Down Expand Up @@ -118,7 +118,7 @@ jobs:
- name: Test
run: |
uv run --no-project python -c "import numpy; print('numpy', numpy.__version__)"
uv run --no-project pytest tests
uv run --no-project pytest tests -m "not perf"

# Early warning: NumPy's nightly builds on the newest CPython. Not a release
# gate; it only runs on the schedule or by hand.
Expand Down Expand Up @@ -151,7 +151,7 @@ jobs:
- name: Test
run: |
uv run --no-sync python -c "import numpy; print('numpy', numpy.__version__)"
uv run --no-sync pytest tests
uv run --no-sync pytest tests -m "not perf"

publish:
name: Publish to PyPI
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,16 @@ test = [
[tool.setuptools.dynamic]
readme = {file = "README.md", content-type = "text/markdown"}

[tool.pytest.ini_options]
markers = [
"perf: timing benchmarks; flaky on shared CI runners, so CI deselects them with -m 'not perf'",
]

[tool.setuptools_scm]

[tool.cibuildwheel]
test-groups = ["test"]
test-command = "pytest {project}/tests"
test-command = "pytest {project}/tests -m \"not perf\""
build-frontend = "build[uv]"
build = ["cp311-*", "cp312-*", "cp313-*", "cp314-*"]
# Skip 32-bit builds and musllinux wheels
Expand Down
4 changes: 4 additions & 0 deletions tests/test_asyncio_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

import samplerate

# Timing benchmarks: shared CI runners make them flaky, so CI runs
# pytest -m "not perf". Run them locally with plain pytest.
pytestmark = pytest.mark.perf


def is_arm_mac():
"""Check if running on ARM-based macOS (Apple Silicon)."""
Expand Down
5 changes: 5 additions & 0 deletions tests/test_datatype_performance.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import time
import numpy as np
import pytest
import samplerate

# Timing benchmarks: shared CI runners make them flaky, so CI runs
# pytest -m "not perf". Run them locally with plain pytest.
pytestmark = pytest.mark.perf

def benchmark_resample(input_data, ratio=1.5, converter='sinc_fastest'):
start_time = time.perf_counter()
samplerate.resample(input_data, ratio, converter)
Expand Down
6 changes: 6 additions & 0 deletions tests/test_threading_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def producer():
return output


@pytest.mark.perf
@pytest.mark.parametrize("num_threads", [2, 4, 6, 8])
@pytest.mark.parametrize("converter_type", ["sinc_fastest", "sinc_medium", "sinc_best"])
def test_resample_gil_release_parallel(num_threads, converter_type):
Expand Down Expand Up @@ -119,6 +120,7 @@ def test_resample_gil_release_parallel(num_threads, converter_type):
print(f" ✓ Performance meets expectations ({expected_speedup}x)")


@pytest.mark.perf
@pytest.mark.parametrize("num_threads", [2, 4, 6, 8])
@pytest.mark.parametrize("converter_type", ["sinc_fastest", "sinc_medium", "sinc_best"])
def test_resampler_process_gil_release_parallel(num_threads, converter_type):
Expand Down Expand Up @@ -175,6 +177,7 @@ def test_resampler_process_gil_release_parallel(num_threads, converter_type):
print(f" ✓ Performance meets expectations ({expected_speedup}x)")


@pytest.mark.perf
@pytest.mark.parametrize("num_threads", [2, 4, 6, 8])
@pytest.mark.parametrize("converter_type", ["sinc_fastest", "sinc_medium", "sinc_best"])
def test_callback_resampler_gil_release_parallel(num_threads, converter_type):
Expand Down Expand Up @@ -275,6 +278,7 @@ def worker(data, ratio, results, index):
assert np.allclose(results[0], results[1])


@pytest.mark.perf
def test_conditional_gil_release_small_data():
"""Test that small data sizes perform well without GIL release overhead.

Expand Down Expand Up @@ -310,6 +314,7 @@ def test_conditional_gil_release_small_data():
assert per_call_us > 0


@pytest.mark.perf
def test_conditional_gil_release_large_data_threading():
"""Test that large data sizes still benefit from GIL release for threading.

Expand Down Expand Up @@ -430,6 +435,7 @@ def test_release_gil_parameter_invalid():
print("\n Invalid release_gil parameter test passed!")


@pytest.mark.perf
def test_gil_metrics_report():
"""Generate a detailed performance report for GIL release optimization."""
print("\n" + "="*70)
Expand Down
Loading