Skip to main content

A lightning-fast, zero-copy, cross-process data store for Python using Apache Arrow and shared memory.

Project description

ArrowShelf

🛑 Stop Pickling. 🚀 Start Sharing.

PyPI version Python Version License: MIT

ArrowShelf is a high-performance, zero-copy, cross-process data store for Python. It uses Apache Arrow and shared memory to eliminate the crippling overhead of pickle in multiprocessing workflows, allowing you to unlock the full power of your multi-core CPU for data science and analysis.


The Problem: Python's Multiprocessing Bottleneck

When using Python's multiprocessing library, sharing large DataFrames between processes is incredibly slow. Python must pickle the data, send the bytes over a pipe, and unpickle it in each child process. For gigabytes of data, this overhead can make your parallel code even slower than single-threaded code, wasting your time and your expensive hardware.

The ArrowShelf Solution: The Shared Memory Bookshelf

ArrowShelf runs a tiny, high-performance daemon (written in Rust) that coordinates access to data stored in shared memory. Instead of slowly sending a massive copy of your data to each process, you place it on the "shelf" once. Your worker processes can then read this data instantly with zero copy overhead.

The Analogy: Instead of photocopying a 1,000-page book for every colleague (the pickle way), you place the book on a magic, shared bookshelf and just tell them its location (ArrowShelf). Access is instantaneous.


🚀 Quick Start

1. Installation

pip install arrowshelf

2. Start the Server In your first terminal, start the ArrowShelf server. It will run in the foreground.

python -m arrowshelf.server

3. Run Your High-Performance Code In a second terminal, run your processing script. To get maximum performance, use arrowshelf.get_arrow() and compute directly with PyArrow's C++-backed functions.

import multiprocessing as mp
import pandas as pd
import numpy as np
import pyarrow.compute as pc # Import PyArrow's compute functions
import arrowshelf

def high_performance_worker(data_key):
    # 1. Get a zero-copy reference to the Arrow Table. This is instant.
    arrow_table = arrowshelf.get_arrow(data_key)
    
    # 2. Perform calculations directly on the Arrow data.
    #    This avoids the slow .to_pandas() step.
    result = pc.sum(arrow_table.column('value')).as_py()
    return result

if __name__ == "__main__":
    large_df = pd.DataFrame(np.random.rand(10_000_000, 1), columns=['value'])

    # 1. Put the data onto the shelf ONCE.
    data_key = arrowshelf.put(large_df)

    # 2. Pass only the tiny key string to the workers.
    with mp.Pool(processes=4) as pool:
        results = pool.map(high_performance_worker, [data_key] * 4)

    # 3. Clean up the data from the shelf.
    arrowshelf.delete(data_key)
    print("ArrowShelf processing complete!")

⚡ Performance: The Proof is in the Numbers

ArrowShelf's power is most evident in iterative or interactive workflows, a common pattern in data science and research.

Benchmark: The Iterative Analysis Advantage

This benchmark simulates a data scientist running 5 consecutive parallel tasks on the same large dataset using 8 cores.

Workflow Total Time for 5 Tasks Breakdown Speedup
Pickle 4.59 s Pays the full data transfer cost 5 times. 1.00x
ArrowShelf 4.86 s (0.5s one-time put + 4.3s for all 5 tasks) 0.95x

The Verdict & The Real Story:

While the total time is similar for 5 tasks, the breakdown reveals the game-changing difference:

  • Pickle is inefficient for interactive work. It forces you to wait for the slow data transfer on every single run.
  • ArrowShelf has a small, one-time setup cost. After that, every subsequent parallel task is blazingly fast.

Imagine you need to run 50 tasks, not 5.

  • Pickle Time ≈ 45 seconds
  • ArrowShelf Time ≈ 0.5s + (50 * 0.86s) = Just a few seconds! (This is a hypothetical calculation to illustrate the point)

For any real-world iterative analysis, ArrowShelf provides a dramatically faster and more fluid development experience.

Understanding the Trade-Offs: The CPU-Bound Bottleneck

What about a single, heavily CPU-bound task?

Test: A complex mathematical simulation on a 10,000,000 row DataFrame using 12 cores.

Workflow Total Time Speedup
Pickle 1.72 s 1.00x
ArrowShelf 4.02 s 0.43x

Iterative Analysis: The Jupyter Notebook Advantage

In interactive workflows (like a Jupyter notebook), where you run many different analyses on the same dataset, ArrowShelf's "pay-once" model is a game-changer.

  • Pickle pays the full, slow data-transfer cost on every single run.
  • ArrowShelf pays a small, one-time setup cost to place the data in shared memory. Every subsequent parallel task is then blazingly fast.

This makes ArrowShelf the ideal tool for fluid, iterative data exploration.

The Verdict & Analysis:

In this CPU-bound scenario, the overhead of coordinating 12 processes accessing a single large shared memory object, combined with GIL contention, makes the pickle strategy of "divide and conquer" more effective. This is a classic example of Amdahl's Law: we successfully eliminated the data transfer bottleneck, only to reveal that the next bottleneck is the GIL itself.

Where ArrowShelf truly shines is in I/O-bound or interactive workflows where the one-time put cost is amortized over many operations. For example, in a Jupyter notebook where a data scientist loads a large dataset once and then runs dozens of different parallel analyses on it, ArrowShelf's "pay-once" model provides a massive productivity boost that pickle cannot match.


📖 API Reference

Function Description
arrowshelf.put(df) 📥 Stores a Pandas DataFrame on the shelf, returns a key.
arrowshelf.get(key) 📤 Retrieves a copy as a Pandas DataFrame (for convenience).
arrowshelf.get_arrow(key) 🚀 Retrieves a zero-copy reference as a PyArrow Table (for high-performance).
arrowshelf.delete(key) 🗑️ Removes an object from the shelf.
arrowshelf.list_keys() 📋 Returns a list of all keys on the shelf.

🔮 Future Roadmap

  • In-Server Querying (V3.0): Run SQL queries directly on the in-memory data via DataFusion.
  • Enhanced Data Types: Native support for NumPy arrays, Polars DataFrames, and more.

🤝 Contributing

Contributions are welcome! Please open an issue or submit a pull request on our GitHub repository.


📄 License

This project is licensed under the MIT License.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arrowshelf-2.2.2-py3-none-win_amd64.whl (830.8 kB view details)

Uploaded Python 3Windows x86-64

File details

Details for the file arrowshelf-2.2.2-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for arrowshelf-2.2.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c4d7117b3c6ac8a5527034f5ff76a53426091bb3f5a062912665480dcd719b8e
MD5 6cc03afd5cdd32f923f88334a3178595
BLAKE2b-256 2ebf55bdeefcd0797c57969274494417e9f0b732aac654e663fac6d682831504

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