π Pyroid: Python on Rust-Powered Steroids

β‘ Blazing fast Rust-powered utilities to eliminate Python's performance bottlenecks.
πΉ Why Pyroid?
- β
Rust-powered acceleration for CPU-heavy tasks
- β
Simplified architecture with minimal dependencies
- β
Domain-driven design for better organization
- β
Easy Python importsβjust
pip install pyroid
- β
Modular toolkit with optional features
- β
Optimized async operations with unified runtime
- β
Zero-copy buffer protocol for efficient memory usage
- β
Parallel processing for high-throughput workloads
π Table of Contents
π» Installation
pip install pyroid
For development installation:
git clone https://github.com/ao/pyroid.git
cd pyroid
python build_and_install.py
This script will:
- Check if Rust is installed and install it if needed
- Build the Rust code with optimizations
- Install the Python package in development mode
π Feature Overview
Pyroid provides high-performance implementations across multiple domains:
Core Features
- Simplified Architecture: Minimal external dependencies for better maintainability
- Domain-Driven Design: Organized by functionality domains
- Pythonic API: Easy to use from Python with familiar interfaces
- Memory Efficiency: Optimized memory usage for large datasets
- Cross-Platform: Works on Windows, macOS, and Linux
- Unified Async Runtime: Shared Tokio runtime for all async operations
- Zero-Copy Buffer Protocol: Efficient memory management without copying
- GIL-Aware Scheduling: Optimized task scheduling with Python's GIL
- Parallel Processing: Efficient batch processing with adaptive sizing
Module Overview
Math | Numerical computations | vector_operations , matrix_operations , statistics |
String | Text processing | reverse , base64_encode , base64_decode |
Data | Collection and DataFrame operations | filter , map , reduce , dataframe_apply |
I/O | File and network operations | read_file , write_file , http_get , http_post |
Image | Basic image manipulation | create_image , to_grayscale , resize , blur |
ML | Basic machine learning | kmeans , linear_regression , normalize , distance_matrix |
Core | Core functionality | runtime , buffer , parallel |
π§ Feature Flags
Pyroid uses feature flags to allow selective compilation of components:
math | Math operations | Enabled |
text | Text processing | Enabled |
data | Collection and DataFrame operations | Enabled |
io | File and network operations | Enabled |
image | Basic image processing | Enabled |
ml | Basic machine learning | Enabled |
To compile with only specific features, modify your Cargo.toml
:
[dependencies]
pyroid = { version = "0.1.0", default-features = false, features = ["math", "data"] }
Usage Examples
Math Operations
import pyroid
v1 = pyroid.math.Vector([1, 2, 3])
v2 = pyroid.math.Vector([4, 5, 6])
v3 = v1 + v2
print(f"Vector sum: {v3}")
print(f"Dot product: {v1.dot(v2)}")
m1 = pyroid.math.Matrix([[1, 2], [3, 4]])
m2 = pyroid.math.Matrix([[5, 6], [7, 8]])
m3 = m1 * m2
print(f"Matrix product: {m3}")
numbers = [1, 2, 3, 4, 5]
mean = pyroid.math.stats.mean(numbers)
median = pyroid.math.stats.median(numbers)
std_dev = pyroid.math.stats.calc_std(numbers)
print(f"Mean: {mean}, Median: {median}, StdDev: {std_dev}")
String Processing
import pyroid
text = "Hello, world!"
reversed_text = pyroid.text.reverse(text)
uppercase = pyroid.text.to_uppercase(text)
lowercase = pyroid.text.to_lowercase(text)
encoded = pyroid.text.base64_encode(text)
decoded = pyroid.text.base64_decode(encoded)
print(f"Original: {text}")
print(f"Encoded: {encoded}")
print(f"Decoded: {decoded}")
DataFrame Operations
import pyroid
df = pyroid.data.DataFrame({
'id': [1, 2, 3, 4, 5],
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45]
})
result = pyroid.data.apply(df, lambda x: x * 2, axis=0)
print(f"DataFrame: {df}")
print(f"Applied function: {result}")
grouped = pyroid.data.groupby_aggregate(df, "age", {"name": "count"})
print(f"Grouped by age: {grouped}")
Collection Operations
import pyroid
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = pyroid.data.filter(numbers, lambda x: x % 2 == 0)
print(f"Even numbers: {even_numbers}")
squared = pyroid.data.map(numbers, lambda x: x * x)
print(f"Squared numbers: {squared}")
sum_result = pyroid.data.reduce(numbers, lambda x, y: x + y)
print(f"Sum: {sum_result}")
unsorted = [5, 2, 8, 1, 9, 3]
sorted_list = pyroid.data.sort(unsorted, reverse=True)
print(f"Sorted (descending): {sorted_list}")
File I/O Operations
import pyroid
content = pyroid.io.read_file("example.txt")
print(f"File content length: {len(content)}")
pyroid.io.write_file("output.txt", "Hello, world!")
files = ["file1.txt", "file2.txt", "file3.txt"]
contents = pyroid.io.read_files(files)
print(f"Read multiple files: {contents}")
Network Operations
import pyroid
response = pyroid.io.get("https://example.com")
print(f"HTTP GET response length: {len(response)}")
Async Operations
import asyncio
import pyroid
from pyroid.core import runtime, buffer, parallel
async def main():
runtime.init()
print(f"Runtime initialized with {runtime.get_worker_threads()} worker threads")
client = pyroid.AsyncClient()
response = await client.fetch("https://example.com")
print(f"Status code: {response['status']}")
urls = [f"https://example.com/{i}" for i in range(10)]
responses = await client.fetch_many(urls, concurrency=5)
print(f"Fetched {len(responses)} URLs")
file_reader = pyroid.AsyncFileReader("example.txt")
content = await file_reader.read_all()
print(f"File content length: {len(content)}")
zero_copy_buffer = buffer.ZeroCopyBuffer(1024)
data = zero_copy_buffer.get_data()
zero_copy_buffer.set_data(data)
processor = parallel.BatchProcessor(batch_size=1000, adaptive=True)
items = list(range(1000000))
def process_item(x):
return x * x
results = processor.map(items, process_item)
print(f"Processed {len(results)} items")
asyncio.run(main())
For a more comprehensive example, see examples/optimized_async_example.py
.
Image Processing
import pyroid
img = pyroid.image.basic.create_image(100, 100, 3)
for x in range(50):
for y in range(50):
img.set_pixel(x, y, [255, 0, 0])
for x in range(50, 100):
for y in range(50, 100):
img.set_pixel(x, y, [0, 0, 255])
grayscale_img = img.to_grayscale()
resized_img = img.resize(200, 200)
blurred_img = img.blur(2)
brightened_img = img.adjust_brightness(1.5)
width = img.width
height = img.height
channels = img.channels
data = img.data
Machine Learning
import pyroid
data = [
[1.0, 2.0], [1.5, 1.8], [5.0, 8.0],
[8.0, 8.0], [1.0, 0.6], [9.0, 11.0]
]
kmeans_result = pyroid.ml.basic.kmeans(data, k=2)
print(f"K-means centroids: {kmeans_result['centroids']}")
print(f"K-means clusters: {kmeans_result['clusters']}")
X = [[1, 1], [1, 2], [2, 2], [2, 3]]
y = [6, 8, 9, 11]
regression_result = pyroid.ml.basic.linear_regression(X, y)
print(f"Linear regression coefficients: {regression_result['coefficients']}")
print(f"Linear regression intercept: {regression_result['intercept']}")
print(f"Linear regression R-squared: {regression_result['r_squared']}")
normalized_data = pyroid.ml.basic.normalize(data, method="min-max")
print(f"Normalized data (min-max): {normalized_data}")
distance_matrix = pyroid.ml.basic.distance_matrix(data, metric="euclidean")
print(f"Distance matrix shape: {len(distance_matrix)}x{len(distance_matrix[0])}")
π Performance Considerations
Pyroid offers significant performance improvements over pure Python:
- Math operations: Optimized vector and matrix operations
- String processing: Efficient string manipulation and base64 encoding/decoding
- Data operations: Improved collection operations and DataFrame handling
- I/O operations: Efficient file and network operations with async support
- Image processing: Basic image manipulation without external dependencies
- Machine learning: Simple ML algorithms implemented in pure Rust
- Async operations: High-performance async operations with unified runtime
- Zero-copy buffers: Efficient memory management without copying
- Parallel processing: Batch processing with adaptive sizing for optimal performance
For detailed benchmarks and performance comparisons between Pyroid's Rust implementation and Python alternatives, see our Performance Comparison document. Our benchmarks show that Pyroid's Rust implementation can be up to 15,000x faster than equivalent Python code for certain operations, with performance advantages that scale dramatically with data size.
Note: The Python fallback implementations are provided only for development and testing when the Rust components cannot be built. For production use, the Rust implementation is essential to achieve the performance benefits.
Building from Source
To build pyroid from source, you need:
- Rust (1.70.0 or later)
- Python (3.8 or later)
- Cargo (comes with Rust)
The easiest way to build and install pyroid is to use the provided script:
python build_and_install.py
Alternatively, you can build manually:
cargo build --release
pip install -e .
For performance-critical applications, consider using the following optimizations:
-
Verify Rust Implementation: Ensure you're using the high-performance Rust implementation
python check_implementation.py
-
Run Python Tests: Ensure the Python fallback implementations work correctly
python run_tests.py
-
Run Rust Tests: Ensure the Rust implementations work correctly
cargo test --test test_rust_*
cargo test --test test_rust_core
cargo test --test test_rust_math
cargo test --test test_rust_data
cargo test --test test_rust_text
cargo test --test test_rust_io
cargo test --test test_rust_image
cargo test --test test_rust_impl
For detailed information about the Rust tests, see Rust Tests Documentation.
-
Unified Runtime: Initialize the runtime once at the start of your application
from pyroid.core import runtime
runtime.init()
-
Zero-Copy Buffers: Use zero-copy buffers for large data transfers
from pyroid.core import buffer
zero_copy_buffer = buffer.ZeroCopyBuffer(size)
-
Parallel Processing: Use batch processing for CPU-intensive operations
from pyroid.core import parallel
processor = parallel.BatchProcessor(adaptive=True)
results = processor.map(items, process_function)
-
Concurrency Control: Adjust concurrency levels based on your workload
client = pyroid.AsyncClient()
responses = await client.fetch_many(urls, concurrency=optimal_value)
Running Benchmarks and Examples
To run the benchmarks and see the performance improvements:
python build_and_install.py
python -m benchmarks.run_benchmarks --size small --suite async --no-dashboard
python -m benchmarks.run_benchmarks --size small --suite high-throughput --no-dashboard
To run the example demonstrating all the optimized features:
python build_and_install.py
python examples/optimized_async_example.py
π§ Requirements
- Python 3.8+
- Supported platforms: Windows, macOS, Linux
π License
MIT
π₯ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
)
- Commit your changes (
git commit -m 'Add some amazing feature'
)
- Push to the branch (
git push origin feature/amazing-feature
)
- Open a Pull Request