Skip to content

Commit

Permalink
Add some simple benchmarks
Browse files Browse the repository at this point in the history
… to compare performance with serde_urlencoded.
  • Loading branch information
jplatte committed Jan 29, 2024
1 parent 724cb0c commit 79fa323
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ exclude = ["/.github"]
edition = "2021"
rust-version = "1.56"

[lib]
bench = false

[features]
default = ["ryu"]

Expand All @@ -30,3 +33,11 @@ serde = "1.0.136"
assert_matches2 = "0.1.0"
# Some tests use structs that derive Serialize / Deserialize
serde = { version = "1.0.136", features = ["derive"] }

# For benchmarks
divan = "0.1.11"
serde_urlencoded = "0.7.1"

[[bench]]
name = "upstream_comparison"
harness = false
56 changes: 56 additions & 0 deletions benches/upstream_comparison/benches.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::collections::BTreeMap;

// For rust-analyzer, this file is included as a regular module. Make IDE
// functionality work by pretending that the symbols being tested always come
// from `serde_html_form`.
#[cfg(rust_analyzer)]
use serde_html_form::from_str;

use crate::{SimpleEnum, StructForm, StructForm2};

#[divan::bench]
fn deserialize_list_enum() {
from_str::<Vec<(u64, SimpleEnum)>>("10=VariantB&5=VariantC&2=VariantA&1=VariantA").unwrap();
}

#[divan::bench]
fn deserialize_list_duplicate_keys() {
from_str::<Vec<(&str, &str)>>("a=test&b=test&a=test&b=test").unwrap();
}

#[divan::bench]
fn deserialize_map() {
from_str::<BTreeMap<&str, i32>>("a=0&bb=1&ccc=123").unwrap();
}

#[divan::bench]
fn deserialize_map_many_entries() {
from_str::<BTreeMap<i32, i32>>(
"0=0&1=1&2=2&3=3&4=4&5=5&6=6&7=7&8=8&\
200=0&201=1&202=2&203=3&204=4&205=5&206=6&207=7&208=8&\
50=0&51=1&52=2&53=3&54=4&55=5&56=6&57=7&58=8&\
1230=0&1231=1&1232=2&1233=3&1234=4&1235=5&1236=6&1237=7&1238=8&\
80=0&81=1&82=2&83=3&84=4&85=5&86=6&87=7&88=8",
)
.unwrap();
}

#[divan::bench]
fn deserialize_struct_simple() {
from_str::<StructForm>("foo=value").unwrap();
}

#[divan::bench]
fn deserialize_struct_long_parameters() {
from_str::<StructForm2>("float_needs_more_complex_parsing_and_has_very_long_field_name=10")
.unwrap();
}

#[divan::bench]
fn deserialize_struct_long_parameters_2() {
from_str::<StructForm2>(
"float_needs_more_complex_parsing_and_has_very_long_field_name=1.0000000000123&\
optional_field=12300000000000000",
)
.unwrap();
}
46 changes: 46 additions & 0 deletions benches/upstream_comparison/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use serde::Deserialize;

fn main() {
divan::main();
}

#[derive(Deserialize)]
#[allow(dead_code)]
struct StructForm {
foo: String,
}

#[derive(Deserialize)]
#[allow(dead_code)]
struct StructForm2 {
optional_field: Option<u64>,
float_needs_more_complex_parsing_and_has_very_long_field_name: f64,
}

#[derive(Deserialize)]
enum SimpleEnum {
VariantA,
VariantB,
VariantC,
}

// For rust-analyzer, treat `benches.rs` as a regular module.
// The module itself also contains some `cfg(rust_analyzer)` code to include
// the symbols otherwise introduced through the inline modules below.
#[cfg(rust_analyzer)]
mod benches;

// For actual execution, treat `benches.rs` as two modules, one where `from_str`
// from `serde_html_form` is benchmarked, one where `from_str` from
// `serde_urlencoded` is benchmarked.
#[cfg(not(rust_analyzer))]
mod serde_html_form {
use serde_html_form::from_str;
include!("benches.rs");
}

#[cfg(not(rust_analyzer))]
mod serde_urlencoded {
use serde_html_form::from_str;
include!("benches.rs");
}

0 comments on commit 79fa323

Please sign in to comment.