Optimisation: Do not re-sort already sorted parcels in exclusion by_value

This commit is contained in:
RunasSudo 2021-01-03 17:20:13 +11:00
parent 6d3e283d1d
commit 673b531475
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 14 additions and 7 deletions

View File

@ -538,6 +538,7 @@ class WIGSTVCounter(BaseSTVCounter):
if len(cand_ballots) > 0:
__pragma__('opov')
self.candidates[candidate].parcels.append(new_parcel)
self.candidates[candidate]._parcels_sorted = False
__pragma__('noopov')
__pragma__('opov')
@ -590,13 +591,15 @@ class WIGSTVCounter(BaseSTVCounter):
count_card.parcels.remove(parcel)
elif self.options['exclusion'] == 'by_value':
# Sort the ballots by value
ballots = [(b, bv) for p in count_card.parcels for b, bv in p]
__pragma__('opov')
ballots.sort(key=lambda x: x[1] / x[0].value, reverse=True)
# Round to 8 decimal places to consider equality
# FIXME: Work out a better way of doing this
count_card.parcels = groupby(ballots, lambda x: (x[1] / x[0].value).round(8, x[1].ROUND_DOWN))
__pragma__('noopov')
if not count_card._parcels_sorted:
ballots = [(b, bv) for p in count_card.parcels for b, bv in p]
__pragma__('opov')
ballots.sort(key=lambda x: x[1] / x[0].value, reverse=True)
# Round to 8 decimal places to consider equality
# FIXME: Work out a better way of doing this
count_card.parcels = groupby(ballots, lambda x: (x[1] / x[0].value).round(8, x[1].ROUND_DOWN))
count_card._parcels_sorted = True
__pragma__('noopov')
if len(count_card.parcels) > 0:
parcel = count_card.parcels[0]
@ -618,6 +621,7 @@ class WIGSTVCounter(BaseSTVCounter):
if len(cand_ballots) > 0:
__pragma__('opov')
self.candidates[candidate].parcels.append(new_parcel)
self.candidates[candidate]._parcels_sorted = False
__pragma__('noopov')
__pragma__('opov')
@ -669,6 +673,7 @@ class UIGSTVCounter(WIGSTVCounter):
if len(cand_ballots) > 0:
__pragma__('opov')
self.candidates[candidate].parcels.append(new_parcel)
self.candidates[candidate]._parcels_sorted = False
__pragma__('noopov')
__pragma__('opov')
@ -736,6 +741,7 @@ class EGSTVCounter(UIGSTVCounter):
if len(cand_ballots) > 0:
__pragma__('opov')
self.candidates[candidate].parcels.append(new_parcel)
self.candidates[candidate]._parcels_sorted = False
__pragma__('noopov')
__pragma__('opov')

View File

@ -71,6 +71,7 @@ class CountCard:
# Parcel = List[Tuple[Ballot, Num]]
# The exhausted/loss to fraction piles will have only one parcel
self.parcels = []
self._parcels_sorted = False # Optimisation to avoid re-sorting in exclusion by_value
@property
def votes(self):