Skip to content

Add FastBarIterator: native iterator accelerator for python-progressbar - #15

Merged
wolph merged 4 commits into
developfrom
progressbar-iterator
Jul 4, 2026
Merged

wolph merged 4 commits into
developfrom
progressbar-iterator

Conversation

@wolph

@wolph wolph commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Adds a small Cython cdef iterator (speedups.progressbar.FastBarIterator, "Approach B") that wraps an iterable and drives a progressbar2 ProgressBar, counting items in a C field so the per-item loop does no Python attribute writes. bar.value/previous_value are synced only at redraw crossings (~20x/sec, like tqdm.n) and once more at finish.

progressbar2 imports this automatically as the progressbar2[fast] extra and falls back to its pure-Python gate when absent. Measured ~5 ns/iter (~4x faster than rich, ~11x faster than tqdm) vs ~30 ns pure Python.

Protocol consumed from the bar: _fast_begin(), _fast_tick(value), _fast_end(), _fast_end_dirty() + plain attrs value/_next_update/_finished. __dealloc__ calls _fast_end_dirty() on early break/exception so redirected streams are restored (progressbar issue #212).

Includes a .pyi stub and indirect integration tests (Cython modules can't be measured by Python coverage). Companion progressbar2 PR: wolph/python-progressbar#316.

A small Cython cdef iterator (Approach B) that wraps an iterable and drives a
progressbar2 ProgressBar, counting items in a C field so the per-item loop does
no Python attribute writes. `bar.value`/`previous_value` are synced only at
redraw crossings (~20x/sec, like tqdm.n) and once more at finish.

The bar implements a small protocol consumed here: `_fast_begin()`,
`_fast_tick(value)`, `_fast_end()`, `_fast_end_dirty()` plus the plain
attributes `value`, `_next_update`, `_finished`. `__dealloc__` calls
`_fast_end_dirty()` when iteration is abandoned (break/exception) so redirected
streams are restored, matching the generator's GeneratorExit cleanup
(progressbar issue #212).

progressbar2 imports this automatically as the `progressbar2[fast]` extra and
falls back to its pure-Python gate when absent. Measured ~5 ns/iter (~4x faster
than rich) vs ~30 ns pure Python.

Includes a .pyi stub and indirect integration tests (fake bar) since Cython
modules can't be measured by Python coverage.
Copilot AI review requested due to automatic review settings June 24, 2026 02:12

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces a native iterator accelerator (FastBarIterator) implemented in Cython to optimize the performance of progressbar2. It includes the Cython implementation, type stubs, setup configuration, and comprehensive integration tests using a mock progress bar. The feedback suggests catching BaseException instead of Exception in the __dealloc__ method of FastBarIterator to ensure no exceptions escape during teardown or interpreter shutdown.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread speedups/progressbar.pyx Outdated

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

This PR introduces a new Cython-backed iterator accelerator (speedups.progressbar.FastBarIterator) intended to drive progressbar2’s ProgressBar via a small “fast protocol”, reducing per-iteration Python overhead by keeping the counter in a C field and only syncing state at redraw boundaries and at completion.

Changes:

  • Added FastBarIterator as a new Cython extension module (speedups/progressbar.pyx).
  • Added a matching type stub (speedups/progressbar.pyi) and new integration-style tests using a protocol-compatible fake bar (tests/test_progressbar.py).
  • Registered the new extension for build via setup.py.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
speedups/progressbar.pyx Adds the Cython FastBarIterator implementation (fast protocol driver + __dealloc__ dirty-finish teardown).
speedups/progressbar.pyi Provides typing for the new native iterator module.
tests/test_progressbar.py Adds integration tests validating iteration order, tick crossings, and dealloc dirty-finish behavior.
setup.py Includes speedups.progressbar in the cythonized extension list.

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

Comment thread speedups/progressbar.pyx Outdated
Comment thread speedups/progressbar.pyi
Comment thread tests/test_progressbar.py

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4a228f691

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread speedups/progressbar.pyx Outdated
wolph added 3 commits July 4, 2026 13:03
- Finish exactly once on exhaustion: repeated next() on an exhausted
  iterator no longer re-runs bar._fast_end(), matching the pure-Python
  generator fallback.
- Catch BaseException (not Exception) in __dealloc__ so nothing can
  escape teardown during interpreter shutdown.
- Clarify module/stub docstrings: the iterator writes back only
  bar.value; previous_value is maintained by the bar's own
  _fast_tick()/_fast_end() hooks via update()/finish().
- Add tests: dirty finish on consumer/source exceptions, single clean
  finish on repeated next().
numpy 2.3+ stubs use PEP 695 `type` statements, which mypy rejects
when python_version targets <3.12. Pyright keeps enforcing 3.10
compatibility.
@wolph
wolph merged commit b107aeb into develop Jul 4, 2026
24 checks passed
@wolph
wolph deleted the progressbar-iterator branch July 4, 2026 11:10
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.

2 participants