Avoid more allocations in fold
This commit is contained in:
parent
2bce8cfc3f
commit
9a4af322ca
|
@ -343,7 +343,7 @@ where
|
||||||
for<'r> &'r N: ops::Neg<Output=N>
|
for<'r> &'r N: ops::Neg<Output=N>
|
||||||
{
|
{
|
||||||
// Describe count
|
// Describe count
|
||||||
let total_ballots = election.ballots.iter().fold(N::zero(), |acc, b| { acc + &b.orig_value });
|
let total_ballots = election.ballots.iter().fold(N::new(), |mut acc, b| { acc += &b.orig_value; acc });
|
||||||
print!("Count computed by OpenTally (revision {}). Read {:.0} ballots from \"{}\" for election \"{}\". There are {} candidates for {} vacancies. ", crate::VERSION, total_ballots, filename, election.name, election.candidates.iter().filter(|c| !c.is_dummy).count(), election.seats);
|
print!("Count computed by OpenTally (revision {}). Read {:.0} ballots from \"{}\" for election \"{}\". There are {} candidates for {} vacancies. ", crate::VERSION, total_ballots, filename, election.name, election.candidates.iter().filter(|c| !c.is_dummy).count(), election.seats);
|
||||||
let opts_str = opts.describe::<N>();
|
let opts_str = opts.describe::<N>();
|
||||||
if !opts_str.is_empty() {
|
if !opts_str.is_empty() {
|
||||||
|
@ -441,7 +441,7 @@ where
|
||||||
for<'r> &'r N: ops::Neg<Output=N>
|
for<'r> &'r N: ops::Neg<Output=N>
|
||||||
{
|
{
|
||||||
// Header rows
|
// Header rows
|
||||||
let total_ballots = election.ballots.iter().fold(N::zero(), |acc, b| { acc + &b.orig_value });
|
let total_ballots = election.ballots.iter().fold(N::new(), |mut acc, b| { acc += &b.orig_value; acc });
|
||||||
|
|
||||||
// eSTV does not consistently quote records, so we won't use a CSV library here
|
// eSTV does not consistently quote records, so we won't use a CSV library here
|
||||||
println!(r#""Election for","{}""#, election.name);
|
println!(r#""Election for","{}""#, election.name);
|
||||||
|
|
|
@ -301,7 +301,7 @@ impl<'a, N: Number> CountState<'a, N> {
|
||||||
result.push_str(&format!("Exhausted: {:.dps$} ({:.dps$})\n", self.exhausted.votes, self.exhausted.transfers, dps=opts.pp_decimals));
|
result.push_str(&format!("Exhausted: {:.dps$} ({:.dps$})\n", self.exhausted.votes, self.exhausted.transfers, dps=opts.pp_decimals));
|
||||||
result.push_str(&format!("Loss by fraction: {:.dps$} ({:.dps$})\n", self.loss_fraction.votes, self.loss_fraction.transfers, dps=opts.pp_decimals));
|
result.push_str(&format!("Loss by fraction: {:.dps$} ({:.dps$})\n", self.loss_fraction.votes, self.loss_fraction.transfers, dps=opts.pp_decimals));
|
||||||
|
|
||||||
let mut total_vote = self.candidates.iter().filter_map(|(c, cc)| if c.is_dummy { None } else { Some(cc) }).fold(N::zero(), |acc, cc| { acc + &cc.votes });
|
let mut total_vote = self.candidates.iter().filter_map(|(c, cc)| if c.is_dummy { None } else { Some(cc) }).fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||||
total_vote += &self.exhausted.votes;
|
total_vote += &self.exhausted.votes;
|
||||||
total_vote += &self.loss_fraction.votes;
|
total_vote += &self.loss_fraction.votes;
|
||||||
result.push_str(&format!("Total votes: {:.dps$}\n", total_vote, dps=opts.pp_decimals));
|
result.push_str(&format!("Total votes: {:.dps$}\n", total_vote, dps=opts.pp_decimals));
|
||||||
|
|
|
@ -902,11 +902,19 @@ fn update_vre_ers<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
let mut log = String::new();
|
let mut log = String::new();
|
||||||
|
|
||||||
// Calculate active vote
|
// Calculate active vote
|
||||||
let active_vote = state.candidates.values().fold(N::zero(), |acc, cc| {
|
let active_vote = state.candidates.values().fold(N::new(), |mut acc, cc| {
|
||||||
match cc.state {
|
match cc.state {
|
||||||
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
CandidateState::Elected => {
|
||||||
_ => { acc + &cc.votes }
|
if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() {
|
||||||
|
acc += &cc.votes;
|
||||||
|
acc -= state.quota.as_ref().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
acc += &cc.votes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
acc
|
||||||
});
|
});
|
||||||
log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
|
@ -942,11 +950,19 @@ fn update_vre_bulk<N: Number>(state: &mut CountState<N>, _opts: &STVOptions) {
|
||||||
//let mut log = String::new();
|
//let mut log = String::new();
|
||||||
|
|
||||||
// Calculate active vote
|
// Calculate active vote
|
||||||
let active_vote = state.candidates.values().fold(N::zero(), |acc, cc| {
|
let active_vote = state.candidates.values().fold(N::new(), |mut acc, cc| {
|
||||||
match cc.state {
|
match cc.state {
|
||||||
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
CandidateState::Elected => {
|
||||||
_ => { acc + &cc.votes }
|
if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() {
|
||||||
|
acc += &cc.votes;
|
||||||
|
acc -= state.quota.as_ref().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
acc += &cc.votes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
acc
|
||||||
});
|
});
|
||||||
//log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
//log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
|
@ -977,7 +993,7 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
let mut log = String::new();
|
let mut log = String::new();
|
||||||
|
|
||||||
// Calculate the total vote
|
// Calculate the total vote
|
||||||
let total_vote = state.candidates.values().fold(N::zero(), |acc, cc| { acc + &cc.votes });
|
let total_vote = state.candidates.values().fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||||
log.push_str(format!("{:.dps$} usable votes, so the quota is ", total_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("{:.dps$} usable votes, so the quota is ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
||||||
|
@ -992,11 +1008,19 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
let mut log = String::new();
|
let mut log = String::new();
|
||||||
|
|
||||||
// Calculate the active vote
|
// Calculate the active vote
|
||||||
let active_vote = state.candidates.values().fold(N::zero(), |acc, cc| {
|
let active_vote = state.candidates.values().fold(N::new(), |mut acc, cc| {
|
||||||
match cc.state {
|
match cc.state {
|
||||||
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
CandidateState::Elected => {
|
||||||
_ => { acc + &cc.votes }
|
if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() {
|
||||||
|
acc += &cc.votes;
|
||||||
|
acc -= state.quota.as_ref().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
acc += &cc.votes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
acc
|
||||||
});
|
});
|
||||||
log.push_str(format!("Active vote is {:.dps$}, so the quota is is ", active_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("Active vote is {:.dps$}, so the quota is is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
|
@ -1018,7 +1042,7 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
let mut log = String::new();
|
let mut log = String::new();
|
||||||
|
|
||||||
// Calculate the total vote
|
// Calculate the total vote
|
||||||
let total_vote = state.candidates.values().fold(N::zero(), |acc, cc| { acc + &cc.votes });
|
let total_vote = state.candidates.values().fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||||
log.push_str(format!("{:.dps$} usable votes, so the quota is reduced to ", total_vote, dps=opts.pp_decimals).as_str());
|
log.push_str(format!("{:.dps$} usable votes, so the quota is reduced to ", total_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
let quota = total_to_quota(total_vote, state.election.seats, opts);
|
||||||
|
@ -1102,12 +1126,20 @@ fn elect_sure_winners<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOp
|
||||||
// For trailing candidates, count all votes
|
// For trailing candidates, count all votes
|
||||||
total_trailing += hopefuls.iter().skip(num_vacancies).fold(N::new(), |mut acc, (_, cc)| { acc += &cc.votes; acc });
|
total_trailing += hopefuls.iter().skip(num_vacancies).fold(N::new(), |mut acc, (_, cc)| { acc += &cc.votes; acc });
|
||||||
// Add finally any votes awaiting transfer
|
// Add finally any votes awaiting transfer
|
||||||
total_trailing += state.candidates.values().fold(N::zero(), |acc, cc| {
|
total_trailing += state.candidates.values().fold(N::new(), |mut acc, cc| {
|
||||||
match cc.state {
|
match cc.state {
|
||||||
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
CandidateState::Elected => {
|
||||||
CandidateState::Hopeful | CandidateState::Guarded | CandidateState::Withdrawn => { acc }
|
if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() {
|
||||||
CandidateState::Excluded | CandidateState::Doomed => { acc + &cc.votes }
|
acc += &cc.votes;
|
||||||
|
acc -= state.quota.as_ref().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CandidateState::Hopeful | CandidateState::Guarded | CandidateState::Withdrawn => {}
|
||||||
|
CandidateState::Excluded | CandidateState::Doomed => {
|
||||||
|
acc += &cc.votes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
if num_vacancies - 1 < hopefuls.len() {
|
if num_vacancies - 1 < hopefuls.len() {
|
||||||
|
|
|
@ -329,7 +329,7 @@ impl STVOptions {
|
||||||
pub fn describe_count<N: Number>(filename: String, election: &Election<N>, opts: &stv::STVOptions) -> String {
|
pub fn describe_count<N: Number>(filename: String, election: &Election<N>, opts: &stv::STVOptions) -> String {
|
||||||
let mut result = String::from("<p>Count computed by OpenTally (revision ");
|
let mut result = String::from("<p>Count computed by OpenTally (revision ");
|
||||||
result.push_str(crate::VERSION);
|
result.push_str(crate::VERSION);
|
||||||
let total_ballots = election.ballots.iter().fold(N::zero(), |acc, b| { acc + &b.orig_value });
|
let total_ballots = election.ballots.iter().fold(N::new(), |mut acc, b| { acc += &b.orig_value; acc });
|
||||||
result.push_str(&format!(r#"). Read {:.0} ballots from ‘{}’ for election ‘{}’. There are {} candidates for {} vacancies. "#, total_ballots, filename, election.name, election.candidates.iter().filter(|c| !c.is_dummy).count(), election.seats));
|
result.push_str(&format!(r#"). Read {:.0} ballots from ‘{}’ for election ‘{}’. There are {} candidates for {} vacancies. "#, total_ballots, filename, election.name, election.candidates.iter().filter(|c| !c.is_dummy).count(), election.seats));
|
||||||
|
|
||||||
let opts_str = opts.describe::<N>();
|
let opts_str = opts.describe::<N>();
|
||||||
|
@ -605,7 +605,7 @@ pub fn update_results_table<N: Number>(stage_num: usize, state: &CountState<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total votes
|
// Calculate total votes
|
||||||
let mut total_vote = state.candidates.iter().filter_map(|(c, cc)| if c.is_dummy { None } else { Some(cc) }).fold(N::zero(), |acc, cc| { acc + &cc.votes });
|
let mut total_vote = state.candidates.iter().filter_map(|(c, cc)| if c.is_dummy { None } else { Some(cc) }).fold(N::new(), |mut acc, cc| { acc += &cc.votes; acc });
|
||||||
total_vote += &state.exhausted.votes;
|
total_vote += &state.exhausted.votes;
|
||||||
total_vote += &state.loss_fraction.votes;
|
total_vote += &state.loss_fraction.votes;
|
||||||
|
|
||||||
|
@ -622,7 +622,7 @@ pub fn update_results_table<N: Number>(stage_num: usize, state: &CountState<N>,
|
||||||
}
|
}
|
||||||
"ballots_votes" => {
|
"ballots_votes" => {
|
||||||
// Calculate total ballots
|
// Calculate total ballots
|
||||||
let mut total_ballots = state.candidates.values().fold(N::zero(), |acc, cc| { acc + cc.num_ballots() });
|
let mut total_ballots = state.candidates.values().fold(N::new(), |mut acc, cc| { acc += cc.num_ballots(); acc });
|
||||||
total_ballots += state.exhausted.num_ballots();
|
total_ballots += state.exhausted.num_ballots();
|
||||||
result.push(&format!(r#"<td class="{}count">{}</td><td class="count">{}</td>"#, classes_i, pp(&total_ballots, 0), pp(&total_vote, opts.pp_decimals)).into());
|
result.push(&format!(r#"<td class="{}count">{}</td><td class="count">{}</td>"#, classes_i, pp(&total_ballots, 0), pp(&total_vote, opts.pp_decimals)).into());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue