Use rayon to speed up percentage calculations, add readme
This commit is contained in:
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Fast Coster
|
||||||
|
|
||||||
|
A business costing system that is super fast:
|
||||||
|
|
||||||
|
- Money movements in less than a second
|
||||||
|
- Overhead allocation in ~2s for large datasets (~10000 departments) and not flushing every from record - up to 10s when flushing from/to allocations
|
||||||
|
|
||||||
|
## General Notes
|
||||||
|
|
||||||
|
Setting the number of threads in overhead allocation: set RAYON_NUM_THREADS environment variable ([doc](https://github.com/rayon-rs/rayon/blob/master/FAQ.md)).
|
||||||
|
Note multithreading is only currently used to calculate allocation percentages, it is not used in the main allocation processing.
|
||||||
@@ -6,6 +6,10 @@ use std::{
|
|||||||
use csv::Writer;
|
use csv::Writer;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use nalgebra::{DMatrix, Dynamic, LU};
|
use nalgebra::{DMatrix, Dynamic, LU};
|
||||||
|
use rayon::prelude::{
|
||||||
|
IntoParallelIterator, IntoParallelRefIterator, ParallelDrainFull, ParallelDrainRange,
|
||||||
|
ParallelIterator,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{CsvAccount, CsvCost};
|
use crate::{CsvAccount, CsvCost};
|
||||||
@@ -232,8 +236,6 @@ where
|
|||||||
|
|
||||||
// Save overhead ccs, so we later know whether a to cc is overhead or operating
|
// Save overhead ccs, so we later know whether a to cc is overhead or operating
|
||||||
let mut overhead_ccs: HashSet<String> = HashSet::new();
|
let mut overhead_ccs: HashSet<String> = HashSet::new();
|
||||||
// overhead department -> total (summed limit to costs)
|
|
||||||
let mut overhead_cc_totals: HashMap<String, f64> = HashMap::new();
|
|
||||||
// For each overhead area, get the cost centres in the area (overhead cost centres), and get all cost centres
|
// For each overhead area, get the cost centres in the area (overhead cost centres), and get all cost centres
|
||||||
// that fit the limit to criteria for the area (skip any cases of overhead cc = other cc).
|
// that fit the limit to criteria for the area (skip any cases of overhead cc = other cc).
|
||||||
// Then get the totals for the other ccs, by looking in the flat_department_costs, where the
|
// Then get the totals for the other ccs, by looking in the flat_department_costs, where the
|
||||||
@@ -286,7 +288,7 @@ where
|
|||||||
limited_ccs.append(&mut other_ccs);
|
limited_ccs.append(&mut other_ccs);
|
||||||
}
|
}
|
||||||
let mut totals: Vec<(String, String, f64)> = overhead_ccs
|
let mut totals: Vec<(String, String, f64)> = overhead_ccs
|
||||||
.iter()
|
.par_iter()
|
||||||
.flat_map(|overhead_cc| {
|
.flat_map(|overhead_cc| {
|
||||||
let limited = limited_ccs
|
let limited = limited_ccs
|
||||||
.iter()
|
.iter()
|
||||||
@@ -310,11 +312,12 @@ where
|
|||||||
.filter(|(_, _, value)| *value != 0.)
|
.filter(|(_, _, value)| *value != 0.)
|
||||||
.filter(|(from_cc, to_cc, _)| from_cc != to_cc)
|
.filter(|(from_cc, to_cc, _)| from_cc != to_cc)
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
// TODO: Put me back if rayon proves problematic
|
||||||
// Insert is safe, since an overhead cc can only be a part of one area
|
// Insert is safe, since an overhead cc can only be a part of one area
|
||||||
overhead_cc_totals.insert(
|
// overhead_cc_totals.insert(
|
||||||
overhead_cc.clone(),
|
// overhead_cc.clone(),
|
||||||
limited.iter().map(|(_, _, value)| value).sum(),
|
// limited.iter().map(|(_, _, value)| value).sum(),
|
||||||
);
|
// );
|
||||||
limited
|
limited
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -322,6 +325,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// overhead department -> total (summed limit to costs)
|
||||||
|
let mut overhead_cc_totals: HashMap<String, f64> = HashMap::new();
|
||||||
|
// Using rayon and doing another pass later proves to be
|
||||||
|
for (overhead_cc, _, value) in overhead_other_total.iter() {
|
||||||
|
*overhead_cc_totals.entry(overhead_cc.clone()).or_insert(0.) += value;
|
||||||
|
}
|
||||||
|
|
||||||
// Export initial totals for operating departments
|
// Export initial totals for operating departments
|
||||||
if show_from {
|
if show_from {
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user