From 0e7ac4a14c8257ccdbd130cff45af9e7859fc656 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Wed, 2 Jun 2021 00:14:51 +0200 Subject: [PATCH] improve filetree::new performance (#760) we used a BTreeMap where ordering does not matter and HashMap performs much better --- CHANGELOG.md | 1 + Cargo.lock | 1 + Makefile | 7 +++++-- filetreelist/Cargo.toml | 1 + filetreelist/src/filetreeitems.rs | 19 +++++++++++-------- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d04405795a..17fed8aaff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Added - honor `config.showUntrackedFiles` improving speed with a lot of untracked items ([#752](https://github.com/extrawurst/gitui/issues/752)) +- improve performance when opening filetree-tab ([#756](https://github.com/extrawurst/gitui/issues/756)) ## Fixed - wrong file with same name shown in file tree ([#748](https://github.com/extrawurst/gitui/issues/748)) diff --git a/Cargo.lock b/Cargo.lock index e2a2ac09bc..42dc679ad6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -377,6 +377,7 @@ name = "filetreelist" version = "0.1.1" dependencies = [ "pretty_assertions", + "scopetime", "thiserror", ] diff --git a/Makefile b/Makefile index 3eaafd55c0..84b14b2154 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,14 @@ .PHONY: debug build-release release-linux-musl test clippy clippy-pedantic install install-debug +ARGS=-l +# ARGS=-l -d + profile: - cargo run --features=timing,pprof -- -l + cargo run --features=timing,pprof -- ${ARGS} debug: - RUST_BACKTRACE=true cargo run --features=timing -- -l + RUST_BACKTRACE=true cargo run --features=timing -- ${ARGS} build-release: cargo build --release diff --git a/filetreelist/Cargo.toml b/filetreelist/Cargo.toml index 0d8d5d3ce4..4ffe0b7af3 100644 --- a/filetreelist/Cargo.toml +++ b/filetreelist/Cargo.toml @@ -12,6 +12,7 @@ categories = ["command-line-utilities"] keywords = ["gui","cli","terminal","ui","tui"] [dependencies] +scopetime = { path = "../scopetime", version = "0.1" } thiserror = "1.0" [dev-dependencies] diff --git a/filetreelist/src/filetreeitems.rs b/filetreelist/src/filetreeitems.rs index d966afef43..c49edfd202 100644 --- a/filetreelist/src/filetreeitems.rs +++ b/filetreelist/src/filetreeitems.rs @@ -5,7 +5,7 @@ use crate::{ }; use crate::{error::Result, treeitems_iter::TreeItemsIterator}; use std::{ - collections::{BTreeMap, BTreeSet}, + collections::{BTreeSet, HashMap}, path::Path, usize, }; @@ -36,9 +36,12 @@ impl FileTreeItems { fn create_items<'a>( list: &'a [&str], collapsed: &BTreeSet<&String>, - ) -> Result<(Vec, BTreeMap<&'a Path, usize>)> { + ) -> Result<(Vec, HashMap<&'a Path, usize>)> { + // scopetime::scope_time!("create_items"); + let mut items = Vec::with_capacity(list.len()); - let mut paths_added: BTreeMap<&Path, usize> = BTreeMap::new(); + let mut paths_added: HashMap<&Path, usize> = + HashMap::with_capacity(list.len()); for e in list { { @@ -81,7 +84,7 @@ impl FileTreeItems { nodes: &mut Vec, // helps to only add new nodes for paths that were not added before // we also count the number of children a node has for later folding - paths_added: &mut BTreeMap<&'a Path, usize>, + paths_added: &mut HashMap<&'a Path, usize>, collapsed: &BTreeSet<&String>, ) -> Result<()> { let mut ancestors = @@ -91,7 +94,7 @@ impl FileTreeItems { for c in &ancestors { if c.parent().is_some() && !paths_added.contains_key(c) { // add node and set count to have no children - paths_added.entry(c).or_insert(0); + paths_added.insert(c, 0); // increase the number of children in the parent node count if let Some(parent) = c.parent() { @@ -241,7 +244,7 @@ impl FileTreeItems { fn fold_paths( items: &mut Vec, - paths: &BTreeMap<&Path, usize>, + paths: &HashMap<&Path, usize>, ) { let mut i = 0; @@ -335,7 +338,7 @@ mod tests { #[test] fn test_push_path() { let mut items = Vec::new(); - let mut paths: BTreeMap<&Path, usize> = BTreeMap::new(); + let mut paths: HashMap<&Path, usize> = HashMap::new(); FileTreeItems::push_dirs( Path::new("a/b/c"), @@ -361,7 +364,7 @@ mod tests { #[test] fn test_push_path2() { let mut items = Vec::new(); - let mut paths: BTreeMap<&Path, usize> = BTreeMap::new(); + let mut paths: HashMap<&Path, usize> = HashMap::new(); FileTreeItems::push_dirs( Path::new("a/b/c"),