use std::time::Instant;
use pylon_kernel::*;
use pylon_runtime::Runtime;
fn test_manifest() -> AppManifest {
serde_json::from_str(include_str!(
"../../../examples/todo-app/pylon.manifest.json"
))
.unwrap()
}
fn bench(name: &str, iterations: u32, f: impl Fn()) {
for _ in 0..10 {
f();
}
let start = Instant::now();
for _ in 0..iterations {
f();
}
let elapsed = start.elapsed();
let per_op = elapsed / iterations;
let ops_sec = if per_op.as_nanos() > 0 {
1_000_000_000 / per_op.as_nanos()
} else {
0
};
println!(
" {:<30} {:>8} ops {:>10.2?} total {:>8.2?}/op {:>8} ops/sec",
name, iterations, elapsed, per_op, ops_sec
);
}
fn main() {
println!("\npylon runtime benchmarks\n");
let rt = Runtime::in_memory(test_manifest()).unwrap();
bench("insert (User)", 10_000, || {
let _ = rt.insert(
"User",
&serde_json::json!({
"email": format!("user{}@test.com", rand()),
"displayName": "Test User",
"createdAt": "2024-01-01T00:00:00Z"
}),
);
});
let rt = Runtime::in_memory(test_manifest()).unwrap();
let mut ids = Vec::new();
for i in 0..1000 {
let id = rt
.insert(
"User",
&serde_json::json!({
"email": format!("user{i}@test.com"),
"displayName": format!("User {i}"),
"createdAt": "2024-01-01T00:00:00Z"
}),
)
.unwrap();
ids.push(id);
}
let id = ids[500].clone();
bench("get_by_id (User)", 10_000, || {
let _ = rt.get_by_id("User", &id);
});
bench("list (1000 Users)", 1_000, || {
let _ = rt.list("User");
});
bench("lookup (User by email)", 10_000, || {
let _ = rt.lookup("User", "email", "user500@test.com");
});
bench("query_filtered (equality)", 1_000, || {
let _ = rt.query_filtered("User", &serde_json::json!({"displayName": "User 500"}));
});
bench("query_filtered ($like)", 1_000, || {
let _ = rt.query_filtered("User", &serde_json::json!({"email": {"$like": "user5"}}));
});
bench("query_filtered ($order + $limit)", 1_000, || {
let _ = rt.query_filtered(
"User",
&serde_json::json!({"$order": {"displayName": "asc"}, "$limit": 10}),
);
});
let id = ids[0].clone();
bench("update (User)", 10_000, || {
let _ = rt.update("User", &id, &serde_json::json!({"displayName": "Updated"}));
});
bench("delete (User)", 1_000, || {
let id = rt
.insert(
"User",
&serde_json::json!({
"email": format!("del{}@test.com", rand()),
"displayName": "Delete Me",
"createdAt": "2024-01-01T00:00:00Z"
}),
)
.unwrap();
let _ = rt.delete("User", &id);
});
bench("query_graph (User)", 1_000, || {
let _ = rt.query_graph(&serde_json::json!({"User": {}}));
});
bench("query_graph (User with where)", 1_000, || {
let _ =
rt.query_graph(&serde_json::json!({"User": {"where": {"displayName": "User 500"}}}));
});
let rt2 = Runtime::in_memory(test_manifest()).unwrap();
bench("insert (Todo, all fields)", 10_000, || {
let _ = rt2.insert(
"Todo",
&serde_json::json!({
"title": "Buy milk",
"done": false,
"authorId": "user-1",
"createdAt": "2024-01-01T00:00:00Z"
}),
);
});
println!();
}
fn rand() -> u64 {
use std::time::{SystemTime, UNIX_EPOCH};
let t = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default();
t.as_nanos() as u64
}