Обновление: http://avillenas.com/post/interactive-c
Ну, вы можете попробовать это.
Я сделал то, что ты хотел сделать. Нажмите здесь, чтобы увидеть GIF
Компания, создавшая этот сайт , очевидно, делает систему расписания, которая отвечает на этот вопрос в контексте написания кода сотрудниками. Он работает по принципу Монте-Карло моделирования будущего, основанного на прошлом.
Вот как этот алгоритм будет работать в вашей ситуации:
Вы моделируете свою задачу как последовательность микрозадачи, скажем, 1000 из них. Предположим, через час вы выполнили 100 из них. Теперь вы запускаете симуляцию для оставшихся 900 шагов, случайным образом выбирая 90 выполненных микрозадач, складывая их время и умножая на 10. Здесь у вас есть оценка; повторите N раз, и вы получите N оценок оставшегося времени. Обратите внимание, что среднее значение между этими оценками составит около 9 часов - никаких сюрпризов. Но, представляя полученное распределение пользователю, вы честно сообщаете ему шансы, например, «с вероятностью 90% это займет еще 3-15 часов»
Этот алгоритм, по определению, дает полный результат, если задача Рассматриваемый вопрос можно смоделировать как набор независимых, случайных микрозадач. Вы можете получить лучший ответ, только если знаете, чем задача отличается от этой модели: например, у установщиков обычно есть список задач загрузки / распаковки / установки, и скорость для одного не может предсказать другой.
Я не гуру статистики, но я думаю, что если вы внимательно посмотрите на моделирование в этом методе, оно всегда будет возвращать нормальное распределение как сумму большого числа независимых случайных величин. . Следовательно, выполнять его вообще не нужно. По факту,
Я обычно использую экспоненциальное скользящее среднее для вычисления скорости операции с коэффициентом сглаживания, скажем, 0,1, и использую его для вычисления оставшегося времени. Таким образом, все измеренные скорости влияют на текущую скорость, но недавние измерения имеют гораздо больший эффект, чем измерения в далеком прошлом.
В коде это будет выглядеть примерно так:
alpha = 0.1 # smoothing factor
...
speed = (speed * (1 - alpha)) + (currentSpeed * alpha)
Если ваши задачи одинаковы по размеру, currentSpeed
- это просто время, необходимое для выполнения последней задачи. Если задачи имеют разные размеры и вы знаете, что одна задача должна быть i, e, вдвое длиннее другой, вы можете разделить время, необходимое для выполнения задачи, на ее относительный размер, чтобы получить текущую скорость. Используя скорость
, вы можете вычислить оставшееся время, умножив его на общий размер оставшихся задач (или просто на их количество, если задачи однородны).
Надеюсь, мое объяснение достаточно ясное, это немного поздно днем.
В некоторых случаях, когда вам нужно выполнять одну и ту же задачу на регулярной основе, может быть хорошей идеей использовать прошлое время выполнения для усреднения.
Например, у меня есть приложение, загружающее библиотеку iTunes через свой COM-интерфейс. Размер данной библиотеки iTunes обычно не увеличивается значительно от запуска к запуску с точки зрения количества элементов, поэтому в этом примере можно было бы отслеживать последние три времени загрузки и скорости загрузки, а затем усреднять их и вычислить ваше текущее ETA.
Это будет намного более точным, чем мгновенное измерение, и, вероятно, также более последовательным.
Однако этот метод зависит от размера задачи, будучи относительно аналогичным предыдущим,
Хороший вопрос. Если проблема может быть разбита на отдельные части, точный расчет часто работает лучше всего. К сожалению, это может быть не так, даже если вы устанавливаете 50 компонентов, каждый из которых может составлять 2%, но один из них может быть огромным. Одна вещь, в которой я добился умеренного успеха, - это синхронизировать процессор и диск и дать приличную оценку на основе данных наблюдений. Знание того, что определенные контрольные точки действительно являются точкой x, дает вам некоторую возможность скорректировать факторы среды (сеть, активность диска, загрузка процессора). Однако это решение не является общим по своей природе из-за его зависимости от данных наблюдений. Использование дополнительных данных, таких как размер файла rpm, помогло мне сделать мои индикаторы выполнения более точными, но они никогда не являются пуленепробиваемыми.
Я всегда хочу, чтобы эти вещи указывали мне диапазон. Если там было написано: «Скорее всего, это задание будет выполнено за 8–30 минут», то у меня будет некоторое представление о том, какой перерыв мне сделать. Если он подпрыгивает повсюду, мне хочется наблюдать за ним, пока он не успокоится, что является большой тратой времени.
Я не переживаю, это очень маленькая часть приложения. Я говорю им, что происходит, и позволяю им заняться чем-нибудь другим.
Вот то, что я нашел, работает хорошо! Для первых 50% задачи вы предполагаете, что скорость постоянная, и экстраполируете. Прогнозирование времени очень стабильно и не сильно колеблется.
Когда вы набираете 50%, вы переключаете стратегию вычислений. Вы берете оставшуюся часть работы (1-p), затем оглядываетесь во времени в истории своего собственного прогресса и находите (с помощью двоичного поиска и линейной интерполяции), сколько времени вам потребовалось, чтобы выполнить последнее (1 -p) процент и используйте , что в качестве оценки времени завершения.
Итак, если вы сейчас сделали 71%, у вас осталось 29%. Вы оглядываетесь в свою историю и обнаруживаете, как давно вы были (71–29 = 42%) завершены. Сообщите это время как ваше расчетное время прибытия.
Это естественно адаптивно. Если у вас есть X объем работы, он смотрит только на время, необходимое для выполнения X объема работы. В конце, когда вы готовы на 99%, для оценки используются только самые свежие, самые свежие данные.
Конечно, он не идеален, но плавно меняется и особенно точен в самом конце, когда он наиболее полезен.