Use the rolling average of the last n estimations instead of the current estimation for reporting print time left

This commit is contained in:
Gina Häußge 2014-12-18 12:01:01 +01:00
parent d8b95f845c
commit dc2318f404
2 changed files with 36 additions and 12 deletions

View file

@ -384,24 +384,24 @@ class Printer():
def _estimateTotalPrintTime(self, progress, printTime):
if not progress or not printTime:
#self._estimationLogger.info("{progress};{printTime};;;".format(**locals()))
#self._estimationLogger.info("{progress};{printTime};;;;".format(**locals()))
return None
else:
newEstimate = printTime / progress
if self._timeEstimationData.is_stable():
#self._estimationLogger.info("{progress};{printTime};{newEstimate};;".format(**locals()))
return newEstimate
self._timeEstimationData.update(newEstimate)
#averageTotal = self._timeEstimationData.average_total
#averageDistance = self._timeEstimationData.average_distance
#
#self._estimationLogger.info("{progress};{printTime};{newEstimate};{averageTotal};{averageDistance}".format(**locals()))
result = None
if self._timeEstimationData.is_stable():
result = self._timeEstimationData.average_total_rolling
return None
#averageTotal = self._timeEstimationData.average_total
#averageTotalRolling = self._timeEstimationData.average_total_rolling
#averageDistance = self._timeEstimationData.average_distance
#self._estimationLogger.info("{progress};{printTime};{newEstimate};{averageTotal};{averageTotalRolling};{averageDistance}".format(**locals()))
return result
def _setProgressData(self, progress, filepos, printTime, cleanedPrintTime):
estimatedTotalPrintTime = self._estimateTotalPrintTime(progress, cleanedPrintTime)
@ -420,7 +420,7 @@ class Printer():
sub_progress = 1.0
totalPrintTime = (1 - sub_progress) * statisticalTotalPrintTime + sub_progress * estimatedTotalPrintTime
#self._printTimeLogger.info("{progress};{cleanedPrintTime};{estimatedTotalPrintTime};{statisticalTotalPrintTime};{totalPrintTime}".format(**locals()))
self._printTimeLogger.info("{progress};{cleanedPrintTime};{estimatedTotalPrintTime};{statisticalTotalPrintTime};{totalPrintTime}".format(**locals()))
self._progress = progress
self._printTime = printTime
@ -884,6 +884,7 @@ class TimeEstimationHelper(object):
def __init__(self):
import collections
self._distances = collections.deque([], self.__class__.STABLE_ROLLING_WINDOW)
self._totals = collections.deque([], self.__class__.STABLE_ROLLING_WINDOW)
self._sum_total = 0
self._count = 0
self._stable_counter = None
@ -895,6 +896,7 @@ class TimeEstimationHelper(object):
old_average_total = self.average_total
self._sum_total += newEstimate
self._totals.append(newEstimate)
self._count += 1
if old_average_total:
@ -915,6 +917,13 @@ class TimeEstimationHelper(object):
else:
return self._sum_total / self._count
@property
def average_total_rolling(self):
if not self._count or self._count < self.__class__.STABLE_ROLLING_WINDOW:
return None
else:
return sum(self._totals) / len(self._totals)
@property
def average_distance(self):
if not self._count or self._count < self.__class__.STABLE_ROLLING_WINDOW + 1:

View file

@ -34,6 +34,9 @@ class EstimationTestCase(unittest.TestCase):
self.assertEquals(self.estimation_helper.average_total, expected)
@data(
((1.0, 2.0), None), # not enough values, have 1, need 3
((1.0, 2.0, 3.0), None), # not enough values, have 2, need 3
((1.0, 2.0, 3.0, 4.0), 0.5), # average totals: 1.0, 1.5, 2.0, 2.5 => (3 * 0.5 / 3 = 0.5
((1.0, 2.0, 3.0, 4.0, 5.0), 0.5), # average totals: 1.0, 1.5, 2.0, 2.5, 3.0 => (0.5 + 0.5 + 0.5) / 3 = 0.5
((1.0, 2.0, 0.0, 1.0, 2.0), 0.7 / 3) # average totals: 1.0, 1.5, 1.0, 1.0, 1.2 => (0.5 + 0.0 + 0.2) / 3 = 0.7 / 3
)
@ -44,6 +47,18 @@ class EstimationTestCase(unittest.TestCase):
self.assertEquals(self.estimation_helper.average_distance, expected)
@data(
((1.0, 1.0), None),
((1.0, 1.0, 1.0), 1.0),
((1.0, 2.0, 3.0, 4.0, 5.0), 4.0),
)
@unpack
def test_average_total_rolling(self, estimates, expected):
for estimate in estimates:
self.estimation_helper.update(estimate)
self.assertEquals(self.estimation_helper.average_total_rolling, expected)
@data(
((1.0, 1.0, 1.0, 1.0), False), # average totals: 1.0, 1.0, 1.0, 1.0 => 3.0 / 3 = 1.0
((1.0, 1.0, 1.0, 1.0, 1.0), True), # average totals: 1.0, 1.0, 1.0, 1.0, 1.0 => 0.0 / 3 = 0.0