Skip to content

Add benchmarks #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

# Don't commit benchmark data
/benches/data/*.json


# End of https://www.gitignore.io/api/rust
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ pest_derive = "2.0"
serde = "1.0"

[dev-dependencies]
criterion = "0.3.5"
matches = "0.1.8"
serde_derive = "1.0"
serde_json = "1.0"
ureq = "2.4.0" # Used for downloading JSON files for the benchmark

[[bench]]
name = "benchmark"
harness = false
83 changes: 83 additions & 0 deletions benches/benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use criterion::Criterion;
use std::{
fs,
path::{Path, PathBuf},
};

const BENCHMARKS: [(&str, &str); 7] = [
// Small benchmarks
("small_menu", "https://cdn.jsdelivr.net/gh/RichardHightower/json-parsers-benchmark@e6d09a817eafc50a5cad821e0743d565899639d9/data/menu.json"),
("small_rh", "https://cdn.jsdelivr.net/gh/RichardHightower/json-parsers-benchmark@e6d09a817eafc50a5cad821e0743d565899639d9/data/small.json"),

// Medium benchmarks
("med_rh", "https://cdn.jsdelivr.net/gh/RichardHightower/json-parsers-benchmark@e6d09a817eafc50a5cad821e0743d565899639d9/data/medium.json"),
("med_webxml", "https://cdn.jsdelivr.net/gh/RichardHightower/json-parsers-benchmark@e6d09a817eafc50a5cad821e0743d565899639d9/data/webxml.json"),

// Large benchmarks
("large_canada", "https://cdn.jsdelivr.net/gh/miloyip/nativejson-benchmark@c00ff27cd5b059b043c414b8a996938f8f9e9663/data/canada.json"),
("large_citm_catalog", "https://cdn.jsdelivr.net/gh/miloyip/nativejson-benchmark@c00ff27cd5b059b043c414b8a996938f8f9e9663/data/citm_catalog.json"),
("large_twitter", "https://cdn.jsdelivr.net/gh/miloyip/nativejson-benchmark@c00ff27cd5b059b043c414b8a996938f8f9e9663/data/twitter.json"),
];

fn main() {
let mut c = Criterion::default().configure_from_args();

std::env::set_current_dir(
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("benches")
.join("data"),
)
.expect("could not go to benchmark data dir");

let mut agent: Option<ureq::Agent> = None;

// Read or download benchmark files
let benches = BENCHMARKS.map(|(bench_name, url)| {
let filename = PathBuf::from(format!("{}.json", bench_name));
let error = match fs::read_to_string(&filename) {
Ok(json) => return (bench_name, json),
Err(e) => e,
};
eprintln!(
"Failed to read benchmark file {}: {}",
filename.display(),
error
);
eprintln!("Falling back to downloading file from <{}>", url);

let response = agent
.get_or_insert_with(ureq::agent)
.get(url)
.call()
.expect("could not download JSON file");

if response.status() != 200 {
panic!(
"Failed to download JSON: response status was {}",
response.status()
);
}

let json = response
.into_string()
.expect("failed to read JSON response body");

if let Err(e) = fs::write(&filename, &json) {
eprintln!("warning: could not write JSON to file: {}", e);
}

(bench_name, json)
});

eprintln!("Successfully loaded all benchmark JSON files");

for (bench_name, json) in benches {
let value = json5::from_str::<serde_json::Value>(&json).expect("JSON benchmark data invalid");
c.bench_function(&format!("deserialize_{}", bench_name), |b| {
b.iter_with_large_drop(|| json5::from_str::<serde_json::Value>(&json).unwrap())
});
c.bench_function(&format!("serialize_{}", bench_name), |b| {
b.iter(|| json5::to_string(&value).unwrap())
});
}
}
1 change: 1 addition & 0 deletions benches/data/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This folder contains JSON data files downloaded by the benchmarking program at runtime.