Однажды я потратил лучшую часть недели, пытаясь создать плавный, не смущающий индикатор прогресса по очень сложному алгоритму.
Алгоритм состоял из 6 различных шагов. Каждый шаг имел временные характеристики, которые серьезно зависели от A) базовых обрабатываемых данных, не только от «количества» данных, но также от «типа» данных и B) 2 шагов, масштабируемых очень хорошо с увеличением числа процессоров, 2 шага выполнялись в 2 потока, а 2 шага были фактически однопоточными.
Эффективное сочетание данных оказало гораздо большее влияние на время выполнения каждого шага, чем количество ядер.
Решение, которое окончательно взломало его, было действительно довольно простым. Я сделал 6 функций, которые анализировали набор данных и пытались предсказать фактическое время выполнения каждого шага анализа. Эвристика в каждой функции анализировала как анализируемые наборы данных, так и количество процессоров. Основываясь на данных времени выполнения с моего собственного 4-ядерного компьютера, каждая функция в основном возвращала ожидаемое количество миллисекунд, на моем компьютере .
f1 (..) + f2 (..) + f3 (..) + f4 (..) + f5 (..) + f6 (..) = общее время выполнения в миллисекундах
Теперь, учитывая эту информацию, вы можете эффективно узнать, какой процент от общего времени выполнения каждого шага должен занять. Теперь, если вы говорите, что step1 должен занимать 40% времени выполнения, вам нужно выяснить, как генерировать 40 1% событий из этого алгоритма. Скажем, цикл for обрабатывает 100 000 элементов, возможно, вы могли бы сделать:
for (int i = 0; i < numItems; i++){
if (i % (numItems / percentageOfTotalForThisStep) == 0) emitProgressEvent();
.. do the actual processing ..
}
Этот алгоритм дал нам гладкую гладкую полосу прогресса, которая работала безупречно. У вашей технологии реализации могут быть разные формы масштабирования и функции, доступные в индикаторе выполнения, но базовый подход к проблеме одинаков.
И да, на самом деле не имело значения, что эвристические ссылочные номера были разработаны на моей машине - единственная реальная проблема - это если вы хотите изменить числа при работе на другой машине. Но вы все еще знаете соотношение (которое является единственной действительно важной вещью здесь), поэтому вы можете видеть, как ваше локальное оборудование работает не так, как у меня.
Теперь среднестатистический читатель SO может задаться вопросом, почему, черт возьми, кто-то потратил неделю, чтобы сделать плавный индикатор прогресса. Функция была запрошена главным продавцом, и я полагаю, что он использовал ее на совещаниях по продажам для получения контрактов. Деньги говорят;)