refactor: Switch from fnv to fxhash (#444)
Switches to fxhash from fnv, which should be a bit faster.
This commit is contained in:
parent
476aaff45c
commit
405ce64a02
|
@ -77,6 +77,7 @@
|
|||
"fedoracentos",
|
||||
"fpath",
|
||||
"fract",
|
||||
"fxhash",
|
||||
"getpwuid",
|
||||
"gnueabihf",
|
||||
"gotop",
|
||||
|
|
|
@ -248,9 +248,9 @@ dependencies = [
|
|||
"ctrlc",
|
||||
"dirs-next",
|
||||
"fern",
|
||||
"fnv",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"fxhash",
|
||||
"heim",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
|
@ -551,12 +551,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.12"
|
||||
|
@ -673,6 +667,15 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
|
|
|
@ -43,7 +43,7 @@ crossterm = "0.18.2"
|
|||
ctrlc = { version = "3.1", features = ["termination"] }
|
||||
clap = "2.33"
|
||||
dirs-next = "2.0.0"
|
||||
fnv = "1.0.7"
|
||||
fxhash = "0.2.1"
|
||||
futures = "0.3.12"
|
||||
indexmap = "~1.6"
|
||||
itertools = "0.10.0"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::time::Instant;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use fnv::FnvHashMap;
|
||||
use fxhash::FxHashMap;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use sysinfo::{System, SystemExt};
|
||||
|
@ -85,7 +85,7 @@ pub struct DataCollector {
|
|||
#[cfg(target_os = "linux")]
|
||||
previous_average_cpu_time: Option<(cpu::PastCpuWork, cpu::PastCpuTotal)>,
|
||||
#[cfg(target_os = "linux")]
|
||||
pid_mapping: FnvHashMap<crate::Pid, processes::PrevProcDetails>,
|
||||
pid_mapping: FxHashMap<crate::Pid, processes::PrevProcDetails>,
|
||||
#[cfg(target_os = "linux")]
|
||||
prev_idle: f64,
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -116,7 +116,7 @@ impl DataCollector {
|
|||
#[cfg(target_os = "linux")]
|
||||
previous_average_cpu_time: None,
|
||||
#[cfg(target_os = "linux")]
|
||||
pid_mapping: FnvHashMap::default(),
|
||||
pid_mapping: FxHashMap::default(),
|
||||
#[cfg(target_os = "linux")]
|
||||
prev_idle: 0_f64,
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::utils::error;
|
|||
use crate::utils::error::BottomError;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use sysinfo::{ProcessExt, ProcessorExt, System, SystemExt};
|
||||
|
@ -338,9 +338,9 @@ fn get_uid_and_gid(path: &Path) -> (Option<u32>, Option<u32>) {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn read_proc(
|
||||
pid: Pid, cpu_usage: f64, cpu_fraction: f64,
|
||||
pid_mapping: &mut FnvHashMap<Pid, PrevProcDetails>, use_current_cpu_total: bool,
|
||||
time_difference_in_secs: u64, mem_total_kb: u64, page_file_kb: u64,
|
||||
pid: Pid, cpu_usage: f64, cpu_fraction: f64, pid_mapping: &mut FxHashMap<Pid, PrevProcDetails>,
|
||||
use_current_cpu_total: bool, time_difference_in_secs: u64, mem_total_kb: u64,
|
||||
page_file_kb: u64,
|
||||
) -> error::Result<ProcessHarvest> {
|
||||
use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
|
@ -491,13 +491,13 @@ fn read_proc(
|
|||
#[cfg(target_os = "linux")]
|
||||
pub fn get_process_data(
|
||||
prev_idle: &mut f64, prev_non_idle: &mut f64,
|
||||
pid_mapping: &mut FnvHashMap<Pid, PrevProcDetails>, use_current_cpu_total: bool,
|
||||
pid_mapping: &mut FxHashMap<Pid, PrevProcDetails>, use_current_cpu_total: bool,
|
||||
time_difference_in_secs: u64, mem_total_kb: u64, page_file_kb: u64,
|
||||
) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
|
||||
// TODO: [PROC THREADS] Add threads
|
||||
|
||||
if let Ok((cpu_usage, cpu_fraction)) = cpu_usage_calculation(prev_idle, prev_non_idle) {
|
||||
let mut pids_to_clear: FnvHashSet<Pid> = pid_mapping.keys().cloned().collect();
|
||||
let mut pids_to_clear: FxHashSet<Pid> = pid_mapping.keys().cloned().collect();
|
||||
let process_vector: Vec<ProcessHarvest> = std::fs::read_dir("/proc")?
|
||||
.filter_map(|dir| {
|
||||
if let Ok(dir) = dir {
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
|||
utils::{self, gen_util::*},
|
||||
};
|
||||
use data_harvester::processes::ProcessSorting;
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexSet;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
|
||||
|
@ -584,7 +585,7 @@ pub fn convert_process_data(
|
|||
// TODO [THREAD]: Thread highlighting and hiding support
|
||||
// For macOS see https://github.com/hishamhm/htop/pull/848/files
|
||||
|
||||
let mut complete_pid_set: fnv::FnvHashSet<Pid> =
|
||||
let mut complete_pid_set: fxhash::FxHashSet<Pid> =
|
||||
existing_converted_process_data.keys().copied().collect();
|
||||
|
||||
for process in ¤t_data.process_harvest {
|
||||
|
@ -724,10 +725,12 @@ pub fn tree_process_data(
|
|||
|
||||
// Let's first build up a (really terrible) parent -> child mapping...
|
||||
// At the same time, let's make a mapping of PID -> process data!
|
||||
let mut parent_child_mapping: HashMap<Pid, IndexSet<Pid>> = HashMap::default();
|
||||
let mut parent_child_mapping: HashMap<Pid, IndexSet<Pid, FxBuildHasher>> = HashMap::default();
|
||||
let mut pid_process_mapping: HashMap<Pid, &ConvertedProcessData> = HashMap::default(); // We actually already have this stored, but it's unfiltered... oh well.
|
||||
let mut orphan_set: IndexSet<Pid> = IndexSet::new();
|
||||
let mut collapsed_set: IndexSet<Pid> = IndexSet::new();
|
||||
let mut orphan_set: IndexSet<Pid, FxBuildHasher> =
|
||||
IndexSet::with_hasher(FxBuildHasher::default());
|
||||
let mut collapsed_set: IndexSet<Pid, FxBuildHasher> =
|
||||
IndexSet::with_hasher(FxBuildHasher::default());
|
||||
|
||||
filtered_process_data.iter().for_each(|process| {
|
||||
if let Some(ppid) = process.ppid {
|
||||
|
@ -740,7 +743,7 @@ pub fn tree_process_data(
|
|||
// Create a mapping for the process if it DNE.
|
||||
parent_child_mapping
|
||||
.entry(process.pid)
|
||||
.or_insert_with(IndexSet::new);
|
||||
.or_insert_with(|| IndexSet::with_hasher(FxBuildHasher::default()));
|
||||
pid_process_mapping.insert(process.pid, process);
|
||||
|
||||
if process.is_collapsed_entry {
|
||||
|
@ -752,7 +755,7 @@ pub fn tree_process_data(
|
|||
orphan_set.remove(&process.pid);
|
||||
parent_child_mapping
|
||||
.entry(ppid)
|
||||
.or_insert_with(IndexSet::new)
|
||||
.or_insert_with(|| IndexSet::with_hasher(FxBuildHasher::default()))
|
||||
.insert(process.pid);
|
||||
}
|
||||
});
|
||||
|
@ -777,10 +780,9 @@ pub fn tree_process_data(
|
|||
|
||||
/// A post-order traversal to correctly prune entire branches that only contain children
|
||||
/// that are disabled and themselves are also disabled ~~wait that sounds wrong~~.
|
||||
///
|
||||
/// Basically, go through the hashmap, and prune out all branches that are no longer relevant.
|
||||
fn prune_disabled_pids(
|
||||
current_pid: Pid, parent_child_mapping: &mut HashMap<Pid, IndexSet<Pid>>,
|
||||
current_pid: Pid, parent_child_mapping: &mut HashMap<Pid, IndexSet<Pid, FxBuildHasher>>,
|
||||
pid_process_mapping: &HashMap<Pid, &ConvertedProcessData>,
|
||||
) -> bool {
|
||||
// Let's explore all the children first, and make sure they (and their children)
|
||||
|
@ -816,7 +818,7 @@ pub fn tree_process_data(
|
|||
|
||||
fn sort_remaining_pids(
|
||||
current_pid: Pid, sort_type: &ProcessSorting, is_sort_descending: bool,
|
||||
parent_child_mapping: &mut HashMap<Pid, IndexSet<Pid>>,
|
||||
parent_child_mapping: &mut HashMap<Pid, IndexSet<Pid, FxBuildHasher>>,
|
||||
pid_process_mapping: &HashMap<Pid, &ConvertedProcessData>,
|
||||
) {
|
||||
// Sorting is special for tree data. So, by default, things are "sorted"
|
||||
|
@ -855,7 +857,7 @@ pub fn tree_process_data(
|
|||
.iter()
|
||||
.rev()
|
||||
.map(|(pid, _proc)| *pid)
|
||||
.collect::<IndexSet<Pid>>();
|
||||
.collect::<IndexSet<Pid, FxBuildHasher>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -964,8 +966,8 @@ pub fn tree_process_data(
|
|||
/// A DFS traversal to correctly build the prefix lines (the pretty '├' and '─' lines) and
|
||||
/// the correct order to the PID tree as a vector.
|
||||
fn build_explored_pids(
|
||||
current_pid: Pid, parent_child_mapping: &HashMap<Pid, IndexSet<Pid>>,
|
||||
prev_drawn_lines: &str, collapsed_set: &IndexSet<Pid>,
|
||||
current_pid: Pid, parent_child_mapping: &HashMap<Pid, IndexSet<Pid, FxBuildHasher>>,
|
||||
prev_drawn_lines: &str, collapsed_set: &IndexSet<Pid, FxBuildHasher>,
|
||||
) -> (Vec<Pid>, Vec<String>) {
|
||||
let mut explored_pids: Vec<Pid> = vec![current_pid];
|
||||
let mut lines: Vec<String> = vec![];
|
||||
|
@ -1062,6 +1064,7 @@ pub fn tree_process_data(
|
|||
&p.name
|
||||
}
|
||||
));
|
||||
|
||||
Some(p)
|
||||
}
|
||||
None => None,
|
||||
|
|
Loading…
Reference in New Issue