Skip to content

Enhance GIL management and error handling in resampling - #31

Open
shauneccles wants to merge 11 commits into
tuxu:masterfrom
LedFx:perf/more_gil_goodness
Open

Enhance GIL management and error handling in resampling#31
shauneccles wants to merge 11 commits into
tuxu:masterfrom
LedFx:perf/more_gil_goodness

Conversation

@shauneccles

Copy link
Copy Markdown

Improve GIL management during resampling operations to prevent blocking and enhance performance. Update error handling to manage exceptions more effectively, particularly in callback scenarios. Adjust the expected output size to accommodate additional frames introduced by #22 and remove support for Python 3.8. Update license specification format.

The latter changes are from existing community PRs that have already been merged.

@shauneccles

shauneccles commented Nov 19, 2025

Copy link
Copy Markdown
Author

For reference this is the results of the asyncio and threading test on my local machine.

PS C:\Users\shaun\python-samplerate-ledfx> uv run pytest tests/test_asyncio_performance.py -s
Uninstalled 1 package in 8ms
Installed 1 package in 10ms
================================================================ test session starts =================================================================
platform win32 -- Python 3.11.9, pytest-9.0.1, pluggy-1.6.0
rootdir: C:\Users\shaun\python-samplerate-ledfx
configfile: pyproject.toml
plugins: asyncio-1.3.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 28 items tests\test_asyncio_performance.py
default loop - sinc_fastest async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.0501s
Parallel: 0.0259s
Speedup: 1.93x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
default loop - sinc_fastest async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.0993s
Parallel: 0.0259s
Speedup: 3.84x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_fastest async with ThreadPoolExecutor (8 concurrent):
Sequential: 0.1991s
Parallel: 0.0302s
Speedup: 6.60x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_medium async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.0987s
Parallel: 0.0495s
Speedup: 1.99x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
default loop - sinc_medium async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.1959s
Parallel: 0.0504s
Speedup: 3.89x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_medium async with ThreadPoolExecutor (8 concurrent):
Sequential: 0.3948s
Parallel: 0.0660s
Speedup: 5.98x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_best async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.3053s
Parallel: 0.1604s
Speedup: 1.90x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
default loop - sinc_best async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.6138s
Parallel: 0.1547s
Speedup: 3.97x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_best async with ThreadPoolExecutor (8 concurrent):
Sequential: 1.2228s
Parallel: 0.1897s
Speedup: 6.44x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_fastest async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.0499s
Parallel: 0.0257s
Speedup: 1.94x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
winloop loop - sinc_fastest async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.1001s
Parallel: 0.0392s
Speedup: 2.55x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_fastest async with ThreadPoolExecutor (8 concurrent):
Sequential: 0.1988s
Parallel: 0.0373s
Speedup: 5.33x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_medium async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.0979s
Parallel: 0.0495s
Speedup: 1.98x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
winloop loop - sinc_medium async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.1960s
Parallel: 0.0576s
Speedup: 3.40x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_medium async with ThreadPoolExecutor (8 concurrent):
Sequential: 0.3957s
Parallel: 0.0548s
Speedup: 7.22x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_best async with ThreadPoolExecutor (2 concurrent):
Sequential: 0.3051s
Parallel: 0.1530s
Speedup: 1.99x
Platform: AMD64
✓ Performance meets expectations (1.1x)
.
winloop loop - sinc_best async with ThreadPoolExecutor (4 concurrent):
Sequential: 0.6071s
Parallel: 0.1605s
Speedup: 3.78x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
winloop loop - sinc_best async with ThreadPoolExecutor (8 concurrent):
Sequential: 1.2146s
Parallel: 0.1851s
Speedup: 6.56x
Platform: AMD64
✓ Performance meets expectations (1.2x)
.
default loop - sinc_fastest blocking vs executor:
Without executor (blocks loop): 0.0100s
With ThreadPoolExecutor: 0.0057s
Improvement: 1.77x
✓ Executor performance meets expectations
.
winloop loop - sinc_fastest blocking vs executor:
Without executor (blocks loop): 0.0100s
With ThreadPoolExecutor: 0.0056s
Improvement: 1.80x
✓ Executor performance meets expectations
.
default loop - 2 concurrent tasks - ThreadPool vs ProcessPool:
ThreadPoolExecutor: 0.0106s
ProcessPoolExecutor: 0.1737s
Ratio: 16.39x
→ ThreadPool is faster
(GIL release makes ThreadPool competitive with ProcessPool)
.
default loop - 4 concurrent tasks - ThreadPool vs ProcessPool:
ThreadPoolExecutor: 0.0109s
ProcessPoolExecutor: 0.1873s
Ratio: 17.14x
→ ThreadPool is faster
(GIL release makes ThreadPool competitive with ProcessPool)
.
winloop loop - 2 concurrent tasks - ThreadPool vs ProcessPool:
ThreadPoolExecutor: 0.0105s
ProcessPoolExecutor: 0.1676s
Ratio: 16.04x
→ ThreadPool is faster
(GIL release makes ThreadPool competitive with ProcessPool)
.
winloop loop - 4 concurrent tasks - ThreadPool vs ProcessPool:
ThreadPoolExecutor: 0.0110s
ProcessPoolExecutor: 0.1850s
Ratio: 16.89x
→ ThreadPool is faster
(GIL release makes ThreadPool competitive with ProcessPool)
.
default loop - Mixed I/O and CPU workload:
Total time: 0.1966s
Tasks completed: 5
✓ Performance meets expectations (< 0.35s)
.
winloop loop - Mixed I/O and CPU workload:
Total time: 0.2021s
Tasks completed: 5
✓ Performance meets expectations (< 0.35s)
.
======================================================================
Asyncio Performance Report
======================================================================
Test Configuration:
Sample rate: 44100 Hz
Duration: 5.0 seconds (220500 samples)
Conversion ratio: 2.0x
Executor: ThreadPoolExecutor
----------------------------------------------------------------------
Converter: sinc_fastest
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.0253s
2 concurrent tasks:
Parallel execution time: 0.0254s
Equivalent sequential time: 0.0507s (2 × 0.0253s)
Speedup: 2.00x
Parallel efficiency: 99.9%
4 concurrent tasks:
Parallel execution time: 0.0265s
Equivalent sequential time: 0.1013s (4 × 0.0253s)
Speedup: 3.82x
Parallel efficiency: 95.6%
----------------------------------------------------------------------
Converter: sinc_medium
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.0493s
2 concurrent tasks:
Parallel execution time: 0.0497s
Equivalent sequential time: 0.0985s (2 × 0.0493s)
Speedup: 1.98x
Parallel efficiency: 99.2%
4 concurrent tasks:
Parallel execution time: 0.0506s
Equivalent sequential time: 0.1970s (4 × 0.0493s)
Speedup: 3.90x
Parallel efficiency: 97.4%
----------------------------------------------------------------------
Converter: sinc_best
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.1524s
2 concurrent tasks:
Parallel execution time: 0.1530s
Equivalent sequential time: 0.3049s (2 × 0.1524s)
Speedup: 1.99x
Parallel efficiency: 99.6%
4 concurrent tasks:
Parallel execution time: 0.1579s
Equivalent sequential time: 0.6098s (4 × 0.1524s)
Speedup: 3.86x
Parallel efficiency: 96.5%
.
======================================================================
Asyncio Performance Report
======================================================================
Test Configuration:
Sample rate: 44100 Hz
Duration: 5.0 seconds (220500 samples)
Conversion ratio: 2.0x
Executor: ThreadPoolExecutor
----------------------------------------------------------------------
Converter: sinc_fastest
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.0253s
2 concurrent tasks:
Parallel execution time: 0.0290s
Equivalent sequential time: 0.0505s (2 × 0.0253s)
Speedup: 1.74x
Parallel efficiency: 87.2%
4 concurrent tasks:
Parallel execution time: 0.0264s
Equivalent sequential time: 0.1010s (4 × 0.0253s)
Speedup: 3.83x
Parallel efficiency: 95.9%
----------------------------------------------------------------------
Converter: sinc_medium
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.0497s
2 concurrent tasks:
Parallel execution time: 0.0579s
Equivalent sequential time: 0.0995s (2 × 0.0497s)
Speedup: 1.72x
Parallel efficiency: 85.9%
4 concurrent tasks:
Parallel execution time: 0.0609s
Equivalent sequential time: 0.1990s (4 × 0.0497s)
Speedup: 3.27x
Parallel efficiency: 81.7%
----------------------------------------------------------------------
Converter: sinc_best
----------------------------------------------------------------------
1 concurrent task (baseline):
Execution time: 0.1542s
2 concurrent tasks:
Parallel execution time: 0.1538s
Equivalent sequential time: 0.3083s (2 × 0.1542s)
Speedup: 2.00x
Parallel efficiency: 100.2%
4 concurrent tasks:
Parallel execution time: 0.1596s
Equivalent sequential time: 0.6167s (4 × 0.1542s)
Speedup: 3.86x
Parallel efficiency: 96.6%
PS C:\Users\shaun\python-samplerate-ledfx> uv run pytest .\tests\test_threading_performance.py -s
================================================================ test session starts =================================================================
platform win32 -- Python 3.11.9, pytest-9.0.1, pluggy-1.6.0
rootdir: C:\Users\shaun\python-samplerate-ledfx
configfile: pyproject.toml
plugins: asyncio-1.3.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 38 items tests\test_threading_performance.py
sinc_fastest with 2 threads:
Sequential: 0.0500s
Parallel: 0.0259s
Speedup: 1.93x
Platform: AMD64
Individual thread times: ['0.0248s', '0.0248s']
✓ Performance meets expectations (1.2x)
.
sinc_fastest with 4 threads:
Sequential: 0.0995s
Parallel: 0.0258s
Speedup: 3.86x
Platform: AMD64
Individual thread times: ['0.0251s', '0.0249s', '0.0249s', '0.0249s']
✓ Performance meets expectations (1.35x)
.
sinc_fastest with 6 threads:
Sequential: 0.1492s
Parallel: 0.0364s
Speedup: 4.10x
Platform: AMD64
Individual thread times: ['0.0318s', '0.0293s', '0.0356s', '0.0252s', '0.0253s', '0.0250s']
✓ Performance meets expectations (1.35x)
.
sinc_fastest with 8 threads:
Sequential: 0.2029s
Parallel: 0.0353s
Speedup: 5.74x
Platform: AMD64
Individual thread times: ['0.0248s', '0.0248s', '0.0248s', '0.0278s', '0.0344s', '0.0318s', '0.0249s', '0.0248s']
✓ Performance meets expectations (1.35x)
.
sinc_medium with 2 threads:
Sequential: 0.0979s
Parallel: 0.0576s
Speedup: 1.70x
Platform: AMD64
Individual thread times: ['0.0570s', '0.0572s']
✓ Performance meets expectations (1.2x)
.
sinc_medium with 4 threads:
Sequential: 0.1957s
Parallel: 0.0590s
Speedup: 3.32x
Platform: AMD64
Individual thread times: ['0.0576s', '0.0584s', '0.0506s', '0.0500s']
✓ Performance meets expectations (1.35x)
.
sinc_medium with 6 threads:
Sequential: 0.2950s
Parallel: 0.0629s
Speedup: 4.69x
Platform: AMD64
Individual thread times: ['0.0614s', '0.0624s', '0.0508s', '0.0503s', '0.0518s', '0.0494s']
✓ Performance meets expectations (1.35x)
.
sinc_medium with 8 threads:
Sequential: 0.3993s
Parallel: 0.0635s
Speedup: 6.29x
Platform: AMD64
Individual thread times: ['0.0588s', '0.0593s', '0.0628s', '0.0551s', '0.0502s', '0.0603s', '0.0596s', '0.0616s']
✓ Performance meets expectations (1.35x)
.
sinc_best with 2 threads:
Sequential: 0.3043s
Parallel: 0.1603s
Speedup: 1.90x
Platform: AMD64
Individual thread times: ['0.1600s', '0.1583s']
✓ Performance meets expectations (1.2x)
.
sinc_best with 4 threads:
Sequential: 0.6091s
Parallel: 0.1609s
Speedup: 3.78x
Platform: AMD64
Individual thread times: ['0.1605s', '0.1572s', '0.1548s', '0.1527s']
✓ Performance meets expectations (1.35x)
.
sinc_best with 6 threads:
Sequential: 0.9121s
Parallel: 0.1678s
Speedup: 5.43x
Platform: AMD64
Individual thread times: ['0.1520s', '0.1667s', '0.1619s', '0.1626s', '0.1535s', '0.1667s']
✓ Performance meets expectations (1.35x)
.
sinc_best with 8 threads:
Sequential: 1.2174s
Parallel: 0.1758s
Speedup: 6.93x
Platform: AMD64
Individual thread times: ['0.1559s', '0.1645s', '0.1569s', '0.1597s', '0.1551s', '0.1746s', '0.1643s', '0.1612s']
✓ Performance meets expectations (1.35x)
.
sinc_fastest Resampler.process() with 2 threads:
Sequential: 0.0499s
Parallel: 0.0254s
Speedup: 1.96x
Platform: AMD64
Individual thread times: ['0.0249s', '0.0249s']
✓ Performance meets expectations (1.1x)
.
sinc_fastest Resampler.process() with 4 threads:
Sequential: 0.1001s
Parallel: 0.0264s
Speedup: 3.79x
Platform: AMD64
Individual thread times: ['0.0252s', '0.0251s', '0.0257s', '0.0252s']
✓ Performance meets expectations (1.25x)
.
sinc_fastest Resampler.process() with 6 threads:
Sequential: 0.1502s
Parallel: 0.0323s
Speedup: 4.65x
Platform: AMD64
Individual thread times: ['0.0249s', '0.0311s', '0.0249s', '0.0250s', '0.0313s', '0.0249s']
✓ Performance meets expectations (1.25x)
.
sinc_fastest Resampler.process() with 8 threads:
Sequential: 0.2012s
Parallel: 0.0271s
Speedup: 7.41x
Platform: AMD64
Individual thread times: ['0.0248s', '0.0251s', '0.0255s', '0.0249s', '0.0250s', '0.0250s', '0.0254s', '0.0253s']
✓ Performance meets expectations (1.25x)
.
sinc_medium Resampler.process() with 2 threads:
Sequential: 0.0981s
Parallel: 0.0495s
Speedup: 1.98x
Platform: AMD64
Individual thread times: ['0.0489s', '0.0491s']
✓ Performance meets expectations (1.1x)
.
sinc_medium Resampler.process() with 4 threads:
Sequential: 0.1961s
Parallel: 0.0506s
Speedup: 3.88x
Platform: AMD64
Individual thread times: ['0.0488s', '0.0489s', '0.0489s', '0.0497s']
✓ Performance meets expectations (1.25x)
.
sinc_medium Resampler.process() with 6 threads:
Sequential: 0.2939s
Parallel: 0.0510s
Speedup: 5.77x
Platform: AMD64
Individual thread times: ['0.0489s', '0.0489s', '0.0488s', '0.0492s', '0.0497s', '0.0490s']
✓ Performance meets expectations (1.25x)
.
sinc_medium Resampler.process() with 8 threads:
Sequential: 0.3920s
Parallel: 0.0575s
Speedup: 6.81x
Platform: AMD64
Individual thread times: ['0.0494s', '0.0491s', '0.0493s', '0.0494s', '0.0499s', '0.0558s', '0.0498s', '0.0558s']
✓ Performance meets expectations (1.25x)
.
sinc_best Resampler.process() with 2 threads:
Sequential: 0.3049s
Parallel: 0.1525s
Speedup: 2.00x
Platform: AMD64
Individual thread times: ['0.1521s', '0.1519s']
✓ Performance meets expectations (1.1x)
.
sinc_best Resampler.process() with 4 threads:
Sequential: 0.6109s
Parallel: 0.1683s
Speedup: 3.63x
Platform: AMD64
Individual thread times: ['0.1580s', '0.1537s', '0.1675s', '0.1623s']
✓ Performance meets expectations (1.25x)
.
sinc_best Resampler.process() with 6 threads:
Sequential: 0.9163s
Parallel: 0.1729s
Speedup: 5.30x
Platform: AMD64
Individual thread times: ['0.1599s', '0.1709s', '0.1721s', '0.1651s', '0.1653s', '0.1574s']
✓ Performance meets expectations (1.25x)
.
sinc_best Resampler.process() with 8 threads:
Sequential: 1.2241s
Parallel: 0.1809s
Speedup: 6.77x
Platform: AMD64
Individual thread times: ['0.1600s', '0.1637s', '0.1769s', '0.1727s', '0.1661s', '0.1792s', '0.1726s', '0.1598s']
✓ Performance meets expectations (1.25x)
.
sinc_fastest CallbackResampler with 2 threads:
Sequential: 0.0504s
Parallel: 0.0258s
Speedup: 1.95x
Platform: AMD64
Individual thread times: ['0.0251s', '0.0252s']
✓ Performance meets expectations (1.2x)
.
sinc_fastest CallbackResampler with 4 threads:
Sequential: 0.1012s
Parallel: 0.0267s
Speedup: 3.79x
Platform: AMD64
Individual thread times: ['0.0258s', '0.0254s', '0.0258s', '0.0258s']
✓ Performance meets expectations (1.2x)
.
sinc_fastest CallbackResampler with 6 threads:
Sequential: 0.1523s
Parallel: 0.0273s
Speedup: 5.58x
Platform: AMD64
Individual thread times: ['0.0270s', '0.0252s', '0.0257s', '0.0256s', '0.0256s', '0.0258s']
✓ Performance meets expectations (1.2x)
.
sinc_fastest CallbackResampler with 8 threads:
Sequential: 0.2013s
Parallel: 0.0404s
Speedup: 4.99x
Platform: AMD64
Individual thread times: ['0.0261s', '0.0397s', '0.0397s', '0.0261s', '0.0252s', '0.0255s', '0.0256s', '0.0260s']
✓ Performance meets expectations (1.2x)
.
sinc_medium CallbackResampler with 2 threads:
Sequential: 0.0985s
Parallel: 0.0499s
Speedup: 1.97x
Platform: AMD64
Individual thread times: ['0.0491s', '0.0495s']
✓ Performance meets expectations (1.2x)
.
sinc_medium CallbackResampler with 4 threads:
Sequential: 0.1970s
Parallel: 0.0593s
Speedup: 3.32x
Platform: AMD64
Individual thread times: ['0.0585s', '0.0588s', '0.0513s', '0.0495s']
✓ Performance meets expectations (1.2x)
.
sinc_medium CallbackResampler with 6 threads:
Sequential: 0.2957s
Parallel: 0.0554s
Speedup: 5.34x
Platform: AMD64
Individual thread times: ['0.0539s', '0.0495s', '0.0495s', '0.0495s', '0.0541s', '0.0495s']
✓ Performance meets expectations (1.2x)
.
sinc_medium CallbackResampler with 8 threads:
Sequential: 0.3935s
Parallel: 0.0775s
Speedup: 5.08x
Platform: AMD64
Individual thread times: ['0.0772s', '0.0696s', '0.0517s', '0.0592s', '0.0596s', '0.0503s', '0.0567s', '0.0668s']
✓ Performance meets expectations (1.2x)
.
sinc_best CallbackResampler with 2 threads:
Sequential: 0.3054s
Parallel: 0.1529s
Speedup: 2.00x
Platform: AMD64
Individual thread times: ['0.1525s', '0.1521s']
✓ Performance meets expectations (1.2x)
.
sinc_best CallbackResampler with 4 threads:
Sequential: 0.6106s
Parallel: 0.1574s
Speedup: 3.88x
Platform: AMD64
Individual thread times: ['0.1570s', '0.1566s', '0.1561s', '0.1524s']
✓ Performance meets expectations (1.2x)
.
sinc_best CallbackResampler with 6 threads:
Sequential: 0.9167s
Parallel: 0.1798s
Speedup: 5.10x
Platform: AMD64
Individual thread times: ['0.1712s', '0.1751s', '0.1734s', '0.1787s', '0.1548s', '0.1551s']
✓ Performance meets expectations (1.2x)
.
sinc_best CallbackResampler with 8 threads:
Sequential: 1.2261s
Parallel: 0.1708s
Speedup: 7.18x
Platform: AMD64
Individual thread times: ['0.1645s', '0.1572s', '0.1671s', '0.1557s', '0.1639s', '0.1564s', '0.1682s', '0.1685s']
✓ Performance meets expectations (1.2x)
..
======================================================================
GIL Release Performance Report
======================================================================
Test Configuration:
Sample rate: 44100 Hz
Duration: 5.0 seconds (220500 samples)
Conversion ratio: 2.0x
----------------------------------------------------------------------
Converter: sinc_fastest
----------------------------------------------------------------------
1 thread (baseline):
Execution time: 0.0249s
2 threads (parallel):
Parallel execution time: 0.0256s
Equivalent sequential time: 0.0498s (2 × 0.0249s)
Speedup: 1.95x
Parallel efficiency: 97.3%
Avg thread time: 0.0250s
4 threads (parallel):
Parallel execution time: 0.0257s
Equivalent sequential time: 0.0995s (4 × 0.0249s)
Speedup: 3.87x
Parallel efficiency: 96.8%
Avg thread time: 0.0249s
----------------------------------------------------------------------
Converter: sinc_medium
----------------------------------------------------------------------
1 thread (baseline):
Execution time: 0.0491s
2 threads (parallel):
Parallel execution time: 0.0494s
Equivalent sequential time: 0.0981s (2 × 0.0491s)
Speedup: 1.98x
Parallel efficiency: 99.2%
Avg thread time: 0.0489s
4 threads (parallel):
Parallel execution time: 0.0505s
Equivalent sequential time: 0.1962s (4 × 0.0491s)
Speedup: 3.89x
Parallel efficiency: 97.2%
Avg thread time: 0.0496s
----------------------------------------------------------------------
Converter: sinc_best
----------------------------------------------------------------------
1 thread (baseline):
Execution time: 0.1527s
2 threads (parallel):
Parallel execution time: 0.1534s
Equivalent sequential time: 0.3055s (2 × 0.1527s)
Speedup: 1.99x
Parallel efficiency: 99.6%
Avg thread time: 0.1529s
4 threads (parallel):
Parallel execution time: 0.1532s
Equivalent sequential time: 0.6110s (4 × 0.1527s)
Speedup: 3.99x
Parallel efficiency: 99.7%
Avg thread time: 0.1524s

Looking at #32 which has same tests on same machine at (about) the same time the headlines from this PR is:

  • Releasing the GIL is a very good thing
    • Basically a linear performance improvement with more threads/concurrency
  • Asyncio + ThreadPoolExecutor is probably the way to go for concurrent resampling

@fakufakufakufaku 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.

This looks pretty good to me. Please just sync with master.
Would it make sense to combine this with your other PR that contains the tests?

matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14"]

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.

This has been merged already. Could you please sync with master?

Comment threadsrc/samplerate.cpp
#endif

// This value was empirically and somewhat arbitrarily chosen; increase it for further safety.
#define END_OF_INPUT_EXTRA_OUTPUT_FRAMES 10000

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.

Could you please add some more details about what this constant controls?

Comment threadsrc/samplerate.cpp
// be more than the expected number of output samples during mid-stream
// steady-state processing. (Also, when the stream is started, the number
// of output samples generated will generally be zero or otherwise less
// than the number of samples in mid-stream processing.)

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.

Is there a maximum we could expect?

Comment threadsrc/samplerate.cpp
output.resize(out_shape);
} else if ((size_t)output_frames_gen >= new_size) {
// This means our fudge factor is too small.
throw std::runtime_error("Generated more output samples than expected!");

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.

Rather than failing, is it possible to truncate the output?

Sign up for freeto 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.

4 participants

@shauneccles@fakufaku@tuxu@arlofaria-cartesia