From 8084309af51c75d742d669ebcf38dac90dc814df Mon Sep 17 00:00:00 2001 From: Wynd Date: Sat, 18 Jan 2025 00:33:24 +0200 Subject: [PATCH] Added divan for benchmarking and some benchmarks --- Cargo.lock | 125 ++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 19 +++++++ benches/commits.rs | 63 +++++++++++++++++++++++ benches/heatmap.rs | 55 ++++++++++++++++++++ src/lib.rs | 4 +- 5 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 benches/commits.rs create mode 100644 benches/heatmap.rs diff --git a/Cargo.lock b/Cargo.lock index e1d2df1..c27f429 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,9 +148,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -180,6 +180,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -212,6 +213,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "condtype" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -227,6 +234,56 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "divan" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0583193020b29b03682d8d33bb53a5b0f50df6daacece12ca99b904cfdcb8c4" +dependencies = [ + "cfg-if", + "clap", + "condtype", + "divan-macros", + "libc", + "regex-lite", +] + +[[package]] +name = "divan-macros" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc51d98e636f5e3b0759a39257458b22619cac7e96d932da6eeb052891bb67c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dunce" version = "1.0.5" @@ -305,8 +362,11 @@ dependencies = [ "anyhow", "chrono", "clap", + "divan", "gix", "itertools", + "mockd", + "rayon", ] [[package]] @@ -925,6 +985,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -988,6 +1054,16 @@ dependencies = [ "adler", ] +[[package]] +name = "mockd" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cb75c56f32efc80a1f79928ba1b9fdb6f6e46d0eea5ddc706d68e5fee604670" +dependencies = [ + "chrono", + "simplerand", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1056,6 +1132,26 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.3" @@ -1071,6 +1167,12 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "rustix" version = "0.38.34" @@ -1131,6 +1233,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simplerand" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e69528fe5b77e9b19f5c4de1fcb8692471bb3325c8876ae62773d318351538" +dependencies = [ + "lazy_static", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -1167,6 +1278,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "terminal_size" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" +dependencies = [ + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" version = "1.0.63" diff --git a/Cargo.toml b/Cargo.toml index fc8ffed..2ea07e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ license = "GPL-3.0-or-later" [lib] name = "libgitheatmap" path = "src/lib.rs" +bench = false [lints.rust] unsafe_code = { level = "forbid" } @@ -25,6 +26,24 @@ clap = { version = "4.5.20", features = ["derive"] } chrono = { version = "0.4.38" } itertools = { version = "0.13.0" } anyhow = { version = "1.0.89" } +rayon = { version = "1.10.0" } + +[dev-dependencies] +divan = { version = "0.1.17" } +mockd = { version = "0.4.35", features = [ + "datetime", + "words", + "name", + "contact", +] } + +[[bench]] +name = "commits" +harness = false + +[[bench]] +name = "heatmap" +harness = false [profile.dev] codegen-backend = "cranelift" diff --git a/benches/commits.rs b/benches/commits.rs new file mode 100644 index 0000000..541cd57 --- /dev/null +++ b/benches/commits.rs @@ -0,0 +1,63 @@ +use anyhow::Context; +use chrono::NaiveDate; +use libgitheatmap::{self, cli::CliArgs}; + +fn main() { + divan::main(); +} + +#[divan::bench] +fn current_repo_commits() { + let home_dir = std::env::current_dir().unwrap(); + + let args = CliArgs { + root_dir: Some(vec![home_dir]), + authors: None, + char: '▩', + repos: None, + ignored_repos: None, + branches: None, + since: "2024-01-01".to_string(), + until: None, + split_months: false, + months_per_row: 13, + no_merges: false, + ..Default::default() + }; + + let since = NaiveDate::parse_from_str(&args.since, "%Y-%m-%d").unwrap(); + + let until = NaiveDate::parse_from_str("2025-01-01", "%Y-%m-%d").unwrap(); + + libgitheatmap::get_commits(args, since, until) + .with_context(|| "Could not fetch commit list") + .unwrap(); +} + +#[divan::bench(sample_count = 20)] +fn all_repos_commits() { + let home_dir = std::path::PathBuf::from("/home"); + + let args = CliArgs { + root_dir: Some(vec![home_dir]), + authors: None, + char: '▩', + repos: None, + ignored_repos: None, + branches: None, + since: "2024-01-01".to_string(), + until: None, + split_months: false, + months_per_row: 13, + no_merges: false, + ..Default::default() + }; + + let since = NaiveDate::parse_from_str(&args.since, "%Y-%m-%d").unwrap(); + + let until = NaiveDate::parse_from_str("2025-01-01", "%Y-%m-%d").unwrap(); + + libgitheatmap::get_commits(args, since, until) + .with_context(|| "Could not fetch commit list") + .unwrap(); +} diff --git a/benches/heatmap.rs b/benches/heatmap.rs new file mode 100644 index 0000000..260b614 --- /dev/null +++ b/benches/heatmap.rs @@ -0,0 +1,55 @@ +use std::sync::OnceLock; + +use chrono::{Local, NaiveDate}; +use gix::{features::hash::Sha1, ObjectId}; +use libgitheatmap::{ + heatmap::{self, Heatmap}, + Commit, +}; + +static COMMITS: OnceLock> = OnceLock::new(); + +fn main() { + let mut commits: Vec = vec![]; + for _n in 0..1000 { + let id = ObjectId::Sha1(Sha1::default().digest()); + let title = mockd::words::sentence(10); + let author = mockd::name::full(); + let email = mockd::contact::email(); + let time = mockd::datetime::date_range( + "2024-01-01T00:00:00Z".to_string(), + "2025-01-01T00:00:00Z".to_string(), + ) + .with_timezone(&Local); + commits.push(Commit::new(id, title, author, email, time)); + } + + COMMITS.set(commits).expect("unable to generate commits"); + + divan::main(); +} + +#[divan::bench] +fn heatmap_generation() { + let since = NaiveDate::parse_from_str("2024-01-01", "%Y-%m-%d").unwrap(); + + let until = NaiveDate::parse_from_str("2025-01-01", "%Y-%m-%d").unwrap(); + + let commits_vec = COMMITS + .get() + .expect("unable to access commits list") + .to_vec(); + let commits = commits_vec.len(); + let repos = 1; + + let _heatmap = Heatmap::new( + since, + until, + commits, + repos, + commits_vec, + false, + 13, + heatmap::Format::Chars, + ); +} diff --git a/src/lib.rs b/src/lib.rs index 0daf908..2347e07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ use anyhow::anyhow; use chrono::{DateTime, Duration, Local, NaiveDate, NaiveTime, TimeZone}; use clap::Parser; use cli::CliArgs; -use gix::{bstr::ByteSlice, features::hash::Sha1, traverse::commit::simple::Sorting, ObjectId}; +use gix::{bstr::ByteSlice, traverse::commit::simple::Sorting, ObjectId}; use heatmap::{ColorLogic, HeatmapColors}; use itertools::Itertools; use mailmap::Mailmap; @@ -45,7 +45,7 @@ pub const RED_COLOR_MAP: [Rgb; 5] = [ Rgb(255, 0, 0), ]; -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Commit { id: ObjectId, title: String,