diff --git a/.gitignore b/.gitignore index d08f46f..7cb30c6 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,6 @@ target/ # mdBook book/book/ + +# Benchmarks +benchmarks/compile/results.md diff --git a/Cargo.lock b/Cargo.lock index e3ad79d..d6efe7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,41 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "diff" version = "0.1.13" @@ -128,6 +163,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -152,6 +193,14 @@ dependencies = [ "utoipa", ] +[[package]] +name = "fortifier-benchmark-compile" +version = "0.0.1" +dependencies = [ + "fortifier", + "validator", +] + [[package]] name = "fortifier-example-basic" version = "0.0.1" @@ -409,6 +458,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.1.0" @@ -563,6 +618,28 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.103" @@ -725,6 +802,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.110" @@ -1029,6 +1112,36 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "validator" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa" +dependencies = [ + "idna", + "once_cell", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca" +dependencies = [ + "darling", + "once_cell", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index f817d0a..7a04653 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["examples/*", "packages/*"] +members = ["benchmarks/*", "examples/*", "packages/*"] resolver = "2" [workspace.package] diff --git a/benchmarks/compile/Cargo.toml b/benchmarks/compile/Cargo.toml new file mode 100644 index 0000000..e817f14 --- /dev/null +++ b/benchmarks/compile/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "fortifier-benchmark-compile" +description = "Fortifier compile time benchmark." + +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true + +[features] +default = [] +fortifier = ["dep:fortifier"] +structs-1-fields-10 = [] +structs-10-fields-10 = [] +validator = ["dep:validator"] + +[dependencies] +fortifier = { workspace = true, features = [ + "email", + "serde", + "url", +], optional = true } +validator = { version = "0.20.0", features = ["derive"], optional = true } + +[lints] +workspace = true diff --git a/benchmarks/compile/run.sh b/benchmarks/compile/run.sh new file mode 100755 index 0000000..45b9ed5 --- /dev/null +++ b/benchmarks/compile/run.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +suites=( + structs-1-fields-10 + structs-10-fields-10 +) + +crates=( + fortifier + validator +) + +hyperfine \ + --setup 'cargo build -p fortifier-benchmark-compile --features={suite},{crate}' \ + --prepare 'cargo clean -p fortifier-benchmark-compile' \ + --shell=none \ + --export-markdown results.md \ + --parameter-list suite "$(IFS=, ; echo "${suites[*]}")" \ + --parameter-list crate "$(IFS=, ; echo "${crates[*]}")" \ + --command-name '{suite} {crate}' \ + 'cargo build -p fortifier-benchmark-compile --features={suite},{crate}' diff --git a/benchmarks/compile/src/lib.rs b/benchmarks/compile/src/lib.rs new file mode 100644 index 0000000..4891d3f --- /dev/null +++ b/benchmarks/compile/src/lib.rs @@ -0,0 +1,4 @@ +#[cfg(feature = "structs-10-fields-10")] +pub mod structs_10_fields_10; +#[cfg(feature = "structs-1-fields-10")] +pub mod structs_1_fields_10; diff --git a/benchmarks/compile/src/structs_10_fields_10.rs b/benchmarks/compile/src/structs_10_fields_10.rs new file mode 100644 index 0000000..ae3a348 --- /dev/null +++ b/benchmarks/compile/src/structs_10_fields_10.rs @@ -0,0 +1,244 @@ +#[cfg(feature = "fortifier")] +use fortifier::Validate; +#[cfg(all(feature = "validator", not(feature = "fortifier")))] +use validator::Validate; + +#[derive(Validate)] +pub struct Struct1 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct2 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct3 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct4 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct5 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct6 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct7 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct8 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct9 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} + +#[derive(Validate)] +pub struct Struct10 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +} diff --git a/benchmarks/compile/src/structs_1_fields_10.rs b/benchmarks/compile/src/structs_1_fields_10.rs new file mode 100644 index 0000000..4424a5c --- /dev/null +++ b/benchmarks/compile/src/structs_1_fields_10.rs @@ -0,0 +1,28 @@ +#[cfg(feature = "fortifier")] +use fortifier::Validate; +#[cfg(all(feature = "validator", not(feature = "fortifier")))] +use validator::Validate; + +#[derive(Validate)] +pub struct Struct1 { + #[validate(length(min = 1, max = 256))] + pub field1: String, + #[validate(length(min = 1, max = 256))] + pub field2: String, + #[validate(length(min = 1, max = 256))] + pub field3: String, + #[validate(length(min = 1, max = 256))] + pub field4: String, + #[validate(length(min = 1, max = 256))] + pub field5: String, + #[validate(length(min = 1, max = 256))] + pub field6: String, + #[validate(length(min = 1, max = 256))] + pub field7: String, + #[validate(length(min = 1, max = 256))] + pub field8: String, + #[validate(length(min = 1, max = 256))] + pub field9: String, + #[validate(length(min = 1, max = 256))] + pub field10: String, +}