Skip to main content

A growable ring-buffer deque: collections.deque API with O(1) indexing and O(k) slicing

Project description

ringdeque

A growable ring-buffer deque for Python: the collections.deque API with O(1) indexing and O(k) slicing, backed by a single contiguous buffer instead of a linked list of blocks.

from ringdeque import deque

d = deque(range(1_000_000))
d[500_000]        # O(1) — collections.deque takes ~250,000 steps here
d[10:20:2]        # O(k) slice, returned as a deque (same maxlen)
d.appendleft(-1)  # all the usual deque operations

Why

collections.deque is a linked list of 64-element blocks: excellent at its ends, O(n) for d[i], no slicing, and a 760-byte floor even when empty. A growable ring buffer (like Rust's VecDeque or C++'s std::deque promise) keeps end-operations fast while making the whole container indexable.

Measured with paired randomized-block benchmarks against collections.deque and arraydeque (full method, caveats, and raw data in bench/RESULTS.md):

  • random access: O(n) → O(1); ~three orders of magnitude at n = 10⁶
  • small deques: 88 B empty vs the stdlib's 760 B (6–9× less memory below ~64 elements)
  • bounded deques (maxlen=): allocation clamped to maxlen + 1 slots — never more memory than the stdlib — and steady-state append tails at stdlib level, where the array-with-slack design (arraydeque) measures 2.5–2.9× worse p99.9/max from perpetual recenter-copies
  • steady-state queue throughput: within ~5% of the stdlib
  • honest costs: growing from empty is ~10% slower and growth reallocations produce rare-but-large latency spikes (the stdlib's block design instead pays a small malloc every 64 appends — a different tail shape, not a free lunch); single-op worst case is O(n) during a growth copy, amortised O(1), and worst-case O(1) at the bounded steady state.

Compatibility

Drop-in for the collections.deque API: append, appendleft, pop, popleft, extend, extendleft, rotate, reverse, clear, copy, count, index, insert, remove, maxlen, iteration, reversed iteration, pickling, weakrefs, subclassing — plus indexing and slicing that collections.deque doesn't have. Semantics are enforced by a differential Hypothesis test suite that runs random operation sequences against collections.deque as the oracle.

Not yet implemented: slice assignment/deletion, + and * operators, O(1) slice views, free-threading (the module currently relies on the GIL). See ROADMAP in the issue tracker.

Install

pip install ringdeque

CPython ≥ 3.11. C extension; wheels planned for common platforms.

License

MIT. The ring-buffer core derives from the author's own CPython experiment branch (faster-cpython/ideas#731); the extension scaffolding is written against the public C API only.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ringdeque-0.1.0a0.tar.gz (16.0 kB view details)

Uploaded Source

File details

Details for the file ringdeque-0.1.0a0.tar.gz.

File metadata

  • Download URL: ringdeque-0.1.0a0.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ringdeque-0.1.0a0.tar.gz
Algorithm Hash digest
SHA256 3666df76bcd2bbbe3a7dc0c79c111bc901728096638540c1c85de4cf9a594d3c
MD5 008733a0f7c410a9b51a614815f724a7
BLAKE2b-256 48420218441fdb26a7f4b3813272e08a524ce3f58d84dddce63470d8dcc5e2da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page