Avoid excess allocations during fold operations
This commit is contained in:
parent
ee7ac064c7
commit
35104055d9
@ -450,7 +450,7 @@ impl<'a, N: Number> CountCard<'a, N> {
|
||||
|
||||
/// Return the number of ballots across all parcels
|
||||
pub fn num_ballots(&self) -> N {
|
||||
return self.parcels.iter().fold(N::new(), |acc, p| acc + p.num_ballots());
|
||||
return self.parcels.iter().fold(N::new(), |mut acc, p| { acc += p.num_ballots(); acc });
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,7 +468,7 @@ pub struct Parcel<'a, N> {
|
||||
impl<'a, N: Number> Parcel<'a, N> {
|
||||
/// Return the number of ballots in this parcel
|
||||
pub fn num_ballots(&self) -> N {
|
||||
return self.votes.iter().fold(N::new(), |acc, v| acc + &v.ballot.orig_value);
|
||||
return self.votes.iter().fold(N::new(), |mut acc, v| { acc += &v.ballot.orig_value; acc });
|
||||
}
|
||||
|
||||
/// Return the value of the votes in this parcel
|
||||
|
@ -82,7 +82,7 @@ where
|
||||
|
||||
// Calculate loss by fraction - if minivoters used
|
||||
if let Some(orig_total) = &state.election.total_votes {
|
||||
let mut total_votes = state.candidates.values().fold(N::new(), |acc, cc| acc + &cc.votes);
|
||||
let mut total_votes = state.candidates.values().fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||
total_votes += &state.exhausted.votes;
|
||||
let lbf = orig_total - &total_votes;
|
||||
|
||||
@ -115,7 +115,7 @@ where
|
||||
|
||||
if !has_surplus.is_empty() {
|
||||
let total_surpluses = has_surplus.iter()
|
||||
.fold(N::new(), |acc, c| acc + &state.candidates[c].votes - quota);
|
||||
.fold(N::new(), |mut acc, c| { acc += &state.candidates[c].votes; acc -= quota; acc });
|
||||
|
||||
// Determine if surplues can be deferred
|
||||
if opts.defer_surpluses {
|
||||
|
@ -254,11 +254,16 @@ impl<'e, N: Number> TransferTable<'e, N> {
|
||||
|
||||
// Sum total votes_out per candidate
|
||||
for (candidate, cell) in self.total.cells.iter_mut() {
|
||||
cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| if let Some(cell) = col.cells.get(candidate) { acc + &cell.votes_out } else { acc });
|
||||
cell.votes_out = self.columns.iter().fold(N::new(), |mut acc, col| {
|
||||
if let Some(cell) = col.cells.get(candidate) {
|
||||
acc += &cell.votes_out
|
||||
}
|
||||
acc
|
||||
});
|
||||
}
|
||||
|
||||
// Sum total exhausted votes
|
||||
self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.exhausted.votes_out);
|
||||
self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |mut acc, col| { acc += &col.exhausted.votes_out; acc });
|
||||
}
|
||||
RoundSubtransfersMode::PerBallot => {
|
||||
// Calculate votes_out for each column
|
||||
@ -316,11 +321,16 @@ impl<'e, N: Number> TransferTable<'e, N> {
|
||||
|
||||
// Sum total votes_out per candidate
|
||||
for (candidate, cell) in self.total.cells.iter_mut() {
|
||||
cell.votes_out = self.columns.iter().fold(N::new(), |acc, col| if let Some(cell) = col.cells.get(candidate) { acc + &cell.votes_out } else { acc });
|
||||
cell.votes_out = self.columns.iter().fold(N::new(), |mut acc, col| {
|
||||
if let Some(cell) = col.cells.get(candidate) {
|
||||
acc += &cell.votes_out;
|
||||
}
|
||||
acc
|
||||
});
|
||||
}
|
||||
|
||||
// Sum total exhausted votes
|
||||
self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |acc, col| acc + &col.exhausted.votes_out);
|
||||
self.total.exhausted.votes_out = self.columns.iter().fold(N::new(), |mut acc, col| { acc += &col.exhausted.votes_out; acc });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ where
|
||||
|
||||
// Calculate loss by fraction - if minivoters used
|
||||
if let Some(orig_total) = &state.election.total_votes {
|
||||
let mut total_votes = state.candidates.values().fold(N::new(), |acc, cc| acc + &cc.votes);
|
||||
let mut total_votes = state.candidates.values().fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||
total_votes += &state.exhausted.votes;
|
||||
let lbf = orig_total - &total_votes;
|
||||
|
||||
@ -241,7 +241,7 @@ where
|
||||
// Distribute if the total surplus exceeds the tolerance
|
||||
let quota_tolerance = N::parse(&opts.meek_surplus_tolerance);
|
||||
let total_surpluses = has_surplus.iter()
|
||||
.fold(N::new(), |acc, c| acc + &state.candidates[c].votes - state.quota.as_ref().unwrap());
|
||||
.fold(N::new(), |mut acc, c| { acc += &state.candidates[c].votes; acc -= state.quota.as_ref().unwrap(); acc });
|
||||
return total_surpluses > quota_tolerance;
|
||||
}
|
||||
}
|
||||
@ -266,7 +266,7 @@ where
|
||||
// Determine if surplues can be deferred
|
||||
if opts.defer_surpluses {
|
||||
let total_surpluses = has_surplus.iter()
|
||||
.fold(N::new(), |acc, c| acc + &state.candidates[c].votes - quota);
|
||||
.fold(N::new(), |mut acc, c| { acc += &state.candidates[c].votes; acc -= quota; acc });
|
||||
if super::can_defer_surpluses(state, opts, &total_surpluses) {
|
||||
state.logger.log_literal(format!("Distribution of surpluses totalling {:.dps$} votes will be deferred.", total_surpluses, dps=opts.pp_decimals));
|
||||
return Ok(false);
|
||||
@ -314,7 +314,7 @@ where
|
||||
// Determine if surplues can be deferred
|
||||
if should_distribute && opts.defer_surpluses {
|
||||
let total_surpluses = has_surplus.iter()
|
||||
.fold(N::new(), |acc, c| acc + &state.candidates[c].votes - quota);
|
||||
.fold(N::new(), |mut acc, c| { acc += &state.candidates[c].votes; acc -= quota; acc });
|
||||
if super::can_defer_surpluses(state, opts, &total_surpluses) {
|
||||
surpluses_deferred = Some(total_surpluses);
|
||||
break;
|
||||
|
@ -1093,15 +1093,14 @@ fn elect_sure_winners<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOp
|
||||
|
||||
let mut total_trailing = N::new();
|
||||
// For leading candidates, count only untransferred surpluses
|
||||
total_trailing += hopefuls.iter().take(num_vacancies).fold(N::new(), |acc, (_, cc)| {
|
||||
total_trailing += hopefuls.iter().take(num_vacancies).fold(N::new(), |mut acc, (_, cc)| {
|
||||
if &cc.votes > state.quota.as_ref().unwrap() {
|
||||
acc + &cc.votes - state.quota.as_ref().unwrap()
|
||||
} else {
|
||||
acc
|
||||
acc += &cc.votes; acc -= state.quota.as_ref().unwrap();
|
||||
}
|
||||
acc
|
||||
});
|
||||
// For trailing candidates, count all votes
|
||||
total_trailing += hopefuls.iter().skip(num_vacancies).fold(N::new(), |acc, (_, cc)| acc + &cc.votes);
|
||||
total_trailing += hopefuls.iter().skip(num_vacancies).fold(N::new(), |mut acc, (_, cc)| { acc += &cc.votes; acc });
|
||||
// Add finally any votes awaiting transfer
|
||||
total_trailing += state.candidates.values().fold(N::zero(), |acc, cc| {
|
||||
match cc.state {
|
||||
@ -1298,7 +1297,7 @@ where
|
||||
let num_to_exclude = to_exclude.len();
|
||||
if num_to_exclude > 0 {
|
||||
let total_excluded = to_exclude.into_iter()
|
||||
.fold(N::new(), |acc, c| acc + &state.candidates[c].votes);
|
||||
.fold(N::new(), |mut acc, c| { acc += &state.candidates[c].votes; acc });
|
||||
if total_surpluses >= &(&hopefuls[num_to_exclude].1.votes - &total_excluded) {
|
||||
return false;
|
||||
}
|
||||
@ -1497,7 +1496,7 @@ fn hopefuls_to_bulk_exclude<'a, N: Number>(state: &CountState<'a, N>, _opts: &ST
|
||||
|
||||
let total_surpluses = state.candidates.iter()
|
||||
.filter(|(_, cc)| !cc.finalised && &cc.votes > state.quota.as_ref().unwrap())
|
||||
.fold(N::new(), |agg, (_, cc)| agg + &cc.votes - state.quota.as_ref().unwrap());
|
||||
.fold(N::new(), |mut acc, (_, cc)| { acc += &cc.votes; acc -= state.quota.as_ref().unwrap(); acc });
|
||||
|
||||
// Attempt to exclude as many candidates as possible
|
||||
for i in 0..hopefuls.len() {
|
||||
@ -1509,7 +1508,7 @@ fn hopefuls_to_bulk_exclude<'a, N: Number>(state: &CountState<'a, N>, _opts: &ST
|
||||
}
|
||||
|
||||
// Do not exclude if this could change the order of exclusion
|
||||
let total_votes = try_exclude.iter().fold(N::new(), |agg, (_, cc)| agg + &cc.votes);
|
||||
let total_votes = try_exclude.iter().fold(N::new(), |mut acc, (_, cc)| { acc += &cc.votes; acc });
|
||||
if i != 0 && total_votes + &total_surpluses >= hopefuls[hopefuls.len()-i].1.votes {
|
||||
continue;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ where
|
||||
|
||||
if opts.sample == SampleMethod::StratifyLR {
|
||||
// Round remainders to remove loss by fraction
|
||||
let transferred = candidate_transfers_remainders.values().fold(N::new(), |acc, (t, _)| acc + t);
|
||||
let transferred = candidate_transfers_remainders.values().fold(N::new(), |mut acc, (t, _)| { acc += t; acc });
|
||||
let loss_fraction = &surplus - &transferred;
|
||||
if !loss_fraction.is_zero() && surplus_fraction.is_some() {
|
||||
let n_to_round: usize = format!("{:.0}", loss_fraction).parse().expect("Loss by fraction overflows usize");
|
||||
|
Loading…
Reference in New Issue
Block a user