less libgit calls and added optional timing logging for benchmarking

This commit is contained in:
Stephan Dilly 2020-03-22 02:17:03 +01:00
parent 55e9fe643b
commit cb247b9e7f
11 changed files with 137 additions and 24 deletions

8
Cargo.lock generated
View file

@ -234,6 +234,7 @@ dependencies = [
"git2",
"itertools 0.9.0",
"log",
"scopetime",
"simplelog",
"tui",
]
@ -522,6 +523,13 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scopetime"
version = "0.1.0"
dependencies = [
"log",
]
[[package]]
name = "signal-hook"
version = "0.1.13"

View file

@ -14,4 +14,9 @@ itertools = "0.9"
log = "0.4"
simplelog = "0.7"
dirs = "2.0"
tui = { version = "0.8", default-features = false, features = ['crossterm'] }
scopetime = { path = "./scopetime" }
tui = { version = "0.8", default-features=false, features = ['crossterm'] }
[features]
default=[]
timing=["scopetime/enabled"]

View file

@ -37,12 +37,9 @@ gitui
* [x] inspect diffs
* [x] commit
* [x] [input polling in thread](assets/perf_compare.jpg)
* [x] only ask git when necessary. maybe in a worker thread?
* [ ] show content of new files
* [ ] put libgit calls in threadpool
* [ ] show content of new unstaged files
* [ ] discard untracked files (remove)
* [ ] use [notify](https://crates.io/crates/notify) to watch git
* [ ] log view
* [ ] stashing support
* [ ] (un)staging selected hunks
# resources (quick links)

12
scopetime/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "scopetime"
version = "0.1.0"
authors = ["Stephan Dilly <dilly.stephan@gmail.com>"]
edition = "2018"
[dependencies]
log = "0.4"
[features]
default=[]
enabled=[]

64
scopetime/src/lib.rs Normal file
View file

@ -0,0 +1,64 @@
use log::trace;
use std::time::Instant;
///
pub struct ScopeTimeLog<'a> {
title: &'a str,
mod_path: &'a str,
file: &'a str,
line: u32,
time: Instant,
}
///
impl<'a> ScopeTimeLog<'a> {
///
pub fn new(
mod_path: &'a str,
title: &'a str,
file: &'a str,
line: u32,
) -> Self {
Self {
title,
mod_path,
file,
line,
time: Instant::now(),
}
}
}
impl<'a> Drop for ScopeTimeLog<'a> {
fn drop(&mut self) {
trace!(
"scopetime: {:?} ms [{}::{}] @{}:{}",
self.time.elapsed().as_millis(),
self.mod_path,
self.title,
self.file,
self.line,
);
}
}
#[cfg(feature = "enabled")]
#[macro_export]
macro_rules! scope_time {
($target:literal) => {
//TODO: add module_path!() aswell?
#[allow(unused_variables)]
let time = $crate::ScopeTimeLog::new(
module_path!(),
$target,
file!(),
line!(),
);
};
}
#[cfg(not(feature = "enabled"))]
#[macro_export]
macro_rules! scope_time {
($target:literal) => {};
}

View file

@ -191,7 +191,8 @@ impl App {
///
pub fn update(&mut self) {
trace!("update");
trace!("app::update");
self.index.update();
self.index_wd.update();
self.update_diff();
@ -230,6 +231,11 @@ impl App {
fn commands(&self) -> Vec<CommandInfo> {
let mut res = Vec::new();
if !self.commit.is_visible() {
res.push(CommandInfo {
name: strings::COMMIT_CMD_OPEN.to_string(),
enabled: !self.index.is_empty(),
});
if self.index_wd.focused() {
let some_selection =
self.index_wd.selection().is_some();

View file

@ -44,10 +44,7 @@ impl Component for CommitComponent {
fn commands(&self) -> Vec<CommandInfo> {
if !self.visible {
vec![CommandInfo {
name: strings::COMMIT_CMD_OPEN.to_string(),
enabled: !git_utils::index_empty(),
}]
vec![]
} else {
vec![
CommandInfo {

View file

@ -1,12 +1,10 @@
use crate::components::CommandInfo;
use crate::components::Component;
use crate::components::{CommandInfo, Component};
use crate::{
git_status::{self, StatusItem},
git_status::{self, StatusItem, StatusItemType},
tui_utils,
};
use crossterm::event::{Event, KeyCode};
use git2::StatusShow;
use git_status::StatusItemType;
use std::{borrow::Cow, cmp};
use tui::{
backend::Backend,
@ -68,6 +66,11 @@ impl IndexComponent {
self.show_selection = focus;
}
///
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
fn move_selection(&mut self, delta: i32) {
let items_len = self.items.len();
if items_len > 0 {

View file

@ -1,5 +1,6 @@
use crate::git_utils;
use git2::{Status, StatusOptions, StatusShow};
use scopetime::scope_time;
#[derive(PartialEq, Copy, Clone)]
pub enum StatusItemType {
@ -33,6 +34,8 @@ pub struct StatusItem {
}
pub fn get_index(show: StatusShow) -> Vec<StatusItem> {
scope_time!("get_index");
let repo = git_utils::repo();
let mut res = Vec::new();

View file

@ -3,6 +3,7 @@ use git2::{
ObjectType, Repository, RepositoryOpenFlags, StatusOptions,
StatusShow,
};
use scopetime::scope_time;
use std::path::Path;
///
@ -33,6 +34,8 @@ pub struct Diff(pub Vec<DiffLine>);
///
pub fn get_diff(p: &Path, stage: bool) -> Diff {
scope_time!("get_diff");
let repo = repo();
let mut opt = DiffOptions::new();
@ -108,6 +111,8 @@ pub fn repo() -> Repository {
///
pub fn commit(msg: &String) {
scope_time!("commit");
let repo = repo();
let signature = repo.signature().unwrap();
@ -131,6 +136,8 @@ pub fn commit(msg: &String) {
///
pub fn index_empty() -> bool {
scope_time!("index_empty");
let repo = repo();
let statuses = repo
@ -143,6 +150,8 @@ pub fn index_empty() -> bool {
}
pub fn stage_add(path: &Path) -> bool {
scope_time!("stage_add");
let repo = repo();
let mut index = repo.index().unwrap();
@ -168,6 +177,8 @@ pub fn stage_add(path: &Path) -> bool {
}
pub fn stage_reset(path: &Path) -> bool {
scope_time!("stage_reset");
let repo = repo();
let reference = repo.head().unwrap();
@ -186,6 +197,8 @@ pub fn stage_reset(path: &Path) -> bool {
}
pub fn index_reset(path: &Path) -> bool {
scope_time!("index_reset");
let repo = repo();
let mut checkout_opts = CheckoutBuilder::new();

View file

@ -18,6 +18,7 @@ use crossterm::{
},
ExecutableCommand, Result,
};
use scopetime::scope_time;
use simplelog::*;
use std::{env, fs, fs::File, io};
use tui::{backend::CrosstermBackend, Terminal};
@ -41,18 +42,22 @@ fn main() -> Result<()> {
loop {
let events = receiver.recv().unwrap();
for e in events {
if let QueueEvent::InputEvent(ev) = e {
app.event(ev);
} else {
app.update();
{
scope_time!("loop");
for e in events {
if let QueueEvent::InputEvent(ev) = e {
app.event(ev);
} else {
app.update();
}
}
}
terminal.draw(|mut f| app.draw(&mut f))?;
terminal.draw(|mut f| app.draw(&mut f))?;
if app.is_quit() {
break;
if app.is_quit() {
break;
}
}
}