Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .axes/axes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ version = "0.6.0"
description = "Blazing fast parallel caching for Rust. Serializes complex data to a chunked file format to get CPU maximum power on data loads, but as a simple binary loader."

[vars]
_cargo_no_features = "<params::no-default-features(alias='-ndf', default=' ')>"
_cargo_all = "<vars::_cargo_features> <vars::_cargo_targets> <vars::_cargo_all_feat_targets>"
_cargo_features = "<params::features(alias='-f', default=' ', literal)>"
_cargo_targets = "<params::targets(alias='-t', default=' ', literal)>"
_cargo_all_feat_targets = "<params::all(map='--all-features --all-targets', default=' ')>"
GREETING = "Hello from an axes variable!"

[scripts]
fmt = "cargo fmt -- --check"
clippy = "cargo clippy <vars::_cargo_all> <params> -- -D warnings"
test = "cargo test <vars::_cargo_all> <params>"
build = "cargo build <vars::_cargo_all>"
fmt = "cargo fmt <params> -- --check"
clippy = "cargo clippy <vars::_cargo_no_features> <vars::_cargo_all> <params> -- -D warnings"
test = "cargo test <vars::_cargo_no_features> <vars::_cargo_all> <params>"
build = "cargo build <vars::_cargo_no_features> <vars::_cargo_all>"

[scripts.check]
run = [
Expand Down
40 changes: 20 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parcode"
version = "0.6.0"
version = "0.6.1"
edition = "2024"
authors = ["RetypeOS"]
description = "A high-performance, lazy load and parallelized caching library for complex Rust data structures."
Expand All @@ -23,15 +23,15 @@ exclude = [
# Local
#parcode-derive = { path = "parcode-derive" }
# Personal
parcode-derive = { version = "0.4.0" }
parcode-derive = { version = "0.4" }
# Third
bincode = { version = "2.0.1", features = ["serde"] }
serde = { version = "1.0.228", features = ["derive", "rc"] }
twox-hash = "2.1.2"
bincode = { version = "2.0", features = ["serde"] }
serde = { version = "1.0", features = ["derive", "rc"] }
twox-hash = "2.1"
# Optional
rayon = { version = "1.11.0", optional = true }
memmap2 = { version = "0.9.9", optional = true }
lz4_flex = { version = "0.12.0", optional = true }
rayon = { version = "1.11", optional = true }
memmap2 = { version = "0.9", optional = true }
lz4_flex = { version = "0.12", optional = true }

[features]
default = ["parallel", "mmap"]
Expand All @@ -41,8 +41,8 @@ lz4_flex = ["dep:lz4_flex"]

[dev-dependencies]
tempfile = "3.24"
criterion = "0.8.1"
serde_bytes = "0.11.19"
criterion = "0.8"
serde_bytes = "0.11"

[[bench]]
name = "performance"
Expand Down
20 changes: 11 additions & 9 deletions benches/lazy_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
use criterion::{Criterion, criterion_group, criterion_main};
use parcode::{Parcode, ParcodeObject};
use serde::{Deserialize, Serialize};
use std::hint::black_box;
use tempfile::NamedTempFile;
use std::{hint::black_box, sync::Arc};

#[derive(Serialize, Deserialize, Clone, ParcodeObject)]
struct HeavyNode {
Expand Down Expand Up @@ -38,22 +37,25 @@ fn bench_lazy(c: &mut Criterion) {
},
};

let file = NamedTempFile::new().expect("Failed to create temp file");
Parcode::save(file.path(), &data).expect("Failed to save parcode data");
let path = file.path().to_owned();

//let file = NamedTempFile::new().expect("Failed to create temp file");
//Parcode::save(file.path(), &data).expect("Failed to save parcode data");
//let path = file.path().to_owned();
let mut buffer = Vec::new();
Parcode::write(&mut buffer, &data).expect("Failed to write parcode data");
let buffer = Arc::new(buffer);
let mut group = c.benchmark_group("Lazy Access");

group.bench_function("full_load", |b| {
b.iter(|| {
let loaded: Root = Parcode::load(&path).expect("Failed to read parcode data");
let loaded: Root =
Parcode::load_bytes(buffer.clone()).expect("Failed to read parcode data");
black_box(loaded.child_a.meta);
});
});

group.bench_function("lazy_meta_only", |b| {
b.iter(|| {
let file_handle = Parcode::open(&path).expect("Failed to open file");
let file_handle = Parcode::open_bytes(buffer.clone()).expect("Failed to open file");
let lazy = file_handle.root::<Root>().expect("Failed to read lazy");
let sum = lazy.child_a.meta + lazy.child_b.meta;
black_box(sum);
Expand All @@ -62,7 +64,7 @@ fn bench_lazy(c: &mut Criterion) {

group.bench_function("lazy_partial_load", |b| {
b.iter(|| {
let file_handle = Parcode::open(&path).expect("Failed to open file");
let file_handle = Parcode::open_bytes(buffer.clone()).expect("Failed to open file");
let lazy = file_handle.root::<Root>().expect("Failed to read lazy");
let payload = lazy.child_a.payload.load().expect("Failed to load payload");
black_box(payload.len());
Expand Down
11 changes: 5 additions & 6 deletions benches/map_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
use criterion::{Criterion, criterion_group, criterion_main};
use parcode::{Parcode, ParcodeObject};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tempfile::NamedTempFile;
use std::{collections::HashMap, sync::Arc};

#[derive(Serialize, Deserialize, ParcodeObject)]
struct MapContainer {
Expand All @@ -21,14 +20,14 @@ fn bench_map(c: &mut Criterion) {
}

let data = MapContainer { opt_map: map };
let file = NamedTempFile::new().expect("Failed to create temp file");
Parcode::save(file.path(), &data).expect("Failed to save parcode data");
let path = file.path().to_owned();
let mut buffer = Vec::new();
Parcode::write(&mut buffer, &data).expect("Failed to write parcode data");
let buffer = Arc::new(buffer);

let mut group = c.benchmark_group("Map Random Access");

group.bench_function("optimized_lookup", |b| {
let file_handle = Parcode::open(&path).expect("Failed to open file");
let file_handle = Parcode::open_bytes(buffer.clone()).expect("Failed to open file");
let lazy = file_handle
.root::<MapContainer>()
.expect("Failed to read lazy");
Expand Down
53 changes: 26 additions & 27 deletions benches/performance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
use criterion::{Criterion, Throughput, criterion_group, criterion_main};
use parcode::{Parcode, ParcodeObject};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::hint::black_box;
use std::io::BufWriter;
use tempfile::NamedTempFile;
use std::io::Cursor;
use std::sync::Arc;

#[derive(Clone, Serialize, Deserialize, ParcodeObject, Debug)]
struct BenchItem {
Expand Down Expand Up @@ -45,12 +44,11 @@ fn bench_writers(c: &mut Criterion) {

// 1. Baseline: Bincode (Single Threaded)
group.bench_function("bincode_serialize", |b| {
let mut buffer = Vec::new();
b.iter(|| {
let file = NamedTempFile::new().expect("Failed to create temp file");
let mut writer = BufWriter::new(file);
bincode::serde::encode_into_std_write(
black_box(raw_data),
&mut writer,
&mut Cursor::new(&mut buffer),
bincode::config::standard(),
)
.expect("Bincode serialization failed");
Expand All @@ -59,9 +57,9 @@ fn bench_writers(c: &mut Criterion) {

// 2. Parcode
group.bench_function("parcode_save", |b| {
let mut buffer = Vec::new();
b.iter(|| {
let file = NamedTempFile::new().expect("Failed to create temp file");
Parcode::save(file.path(), black_box(&data)).expect("Failed to save parcode data");
Parcode::write(&mut buffer, black_box(&data)).expect("Failed to save parcode data");
});
});

Expand All @@ -76,20 +74,20 @@ fn bench_readers(c: &mut Criterion) {
let data = generate_data(item_count);

// Setup files
let bincode_file = NamedTempFile::new().expect("Failed to create temp file");
let mut bincode_buffer = Vec::new();

bincode::serde::encode_into_std_write(
&data.data,
&mut BufWriter::new(&bincode_file),
&mut bincode_buffer,
bincode::config::standard(),
)
.expect("Bincode serialization failed");
let bincode_path = bincode_file.path().to_owned();

let parcode_file = NamedTempFile::new().expect("Failed to create temp file");
Parcode::save(parcode_file.path(), &data).expect("Failed to save parcode data");
let parcode_path = parcode_file.path().to_owned();
let mut parcode_buffer = Vec::new();
Parcode::write(&mut parcode_buffer, &data).expect("Failed to save parcode data");
let parcode_buffer = Arc::new(parcode_buffer);

let file_handle = Parcode::open(&parcode_path).expect("Failed to open file");
let file_handle = Parcode::open_bytes(parcode_buffer.clone()).expect("Failed to open file");
let root = file_handle.root_node().expect("Failed to get root");
println!(
"Chunks detected: {}",
Expand All @@ -101,19 +99,27 @@ fn bench_readers(c: &mut Criterion) {
// 1. Bincode: Standard
group.bench_function("bincode_read_all", |b| {
b.iter(|| {
let file = File::open(&bincode_path).expect("Failed to open file");
let _res: Vec<BenchItem> = bincode::serde::decode_from_std_read(
&mut std::io::BufReader::new(file),
&mut Cursor::new(&bincode_buffer),
bincode::config::standard(),
)
.expect("Bincode deserialization failed");
});
});

// 2. Parcode: Random Access (Single item)
// 2. Parcode: Parallel full load
group.bench_function("parcode_read_all", |b| {
b.iter(|| {
let _res: BenchCollection =
Parcode::load_bytes(parcode_buffer.clone()).expect("Failed to open file");
});
});

// 3. Parcode: Random Access (Single item)
group.bench_function("parcode_random_access_10", |b| {
b.iter(|| {
let file_handle = Parcode::open(&parcode_path).expect("Failed to open file");
let file_handle =
Parcode::open_bytes(parcode_buffer.clone()).expect("Failed to open file");
let root = file_handle
.root::<BenchCollection>()
.expect("Failed to get root");
Expand All @@ -124,17 +130,10 @@ fn bench_readers(c: &mut Criterion) {
});
});

// 3. Parcode: Parallel Stitching
group.bench_function("parcode_read_all_parallel", |b| {
b.iter(|| {
let _res: BenchCollection = Parcode::load(&parcode_path).expect("Failed to open file");
});
});

// 4. Parcode: lazy iterator
group.bench_function("parcode_read_all_iter", |b| {
b.iter(|| {
let file = Parcode::open(&parcode_path).expect("Failed to open file");
let file = Parcode::open_bytes(parcode_buffer.clone()).expect("Failed to open file");
let data = file
.load_lazy::<BenchCollection>()
.expect("Some error was ocurred");
Expand Down
Loading