Я измеряю время сортировки таких алгоритмов, как Bubble, Insert, Selection и Quick sort.
Я использую это для своих целей
long int before = GetTickCount();
QuickSort(pole,0,dlzka-1);
long int after = GetTickCount();
double dif = double((after - before));
cout << "Quick Sort with time "<< dif << " ms " << endl;
Я сортирую массив с 30 000 целых чисел и работаю нормально для другой сортировки, за исключением быстрой сортировки, которая, вероятно, настолько быстра, что сортирует целые 30 000 за менее чем 1 мс, а затем мой таймер говорит, что это 0 мс, что выглядит как ошибка.
Я хочу написать его, например, 0,01 мс, просто чтобы он выглядел так, что он работает корректно.
Спасибо.
Когда вы тестируете, вы никогда не тестируете просто один запустить. Ваш таймер не является точным / точным, чтобы дать значимые результаты в течение этого крошечного промежутка времени.
Например, документация для GetTickCount
говорит:
Разрешение функции GetTickCount ограничено разрешением системного таймера, которое обычно находится в диапазоне от 10 миллисекунд до 16 миллисекунд.
Таким образом, совершенно очевидно, что получение значения 0.01ms это глупость
Вместо этого ориентир много работает, а затем разделите на количество раз, когда вы запускали его.
Поместите свой код в цикл, который вы запускаете 1000 раз, с часами, запущенными и остановленными вне этого цикла. Затем разделите результат на 1000. Или, если хотите, результат синхронизации теперь будет в мкс, а не в мс.
Если ваш цикл очень быстрый, вам может потребоваться более 1000 повторений, чтобы получить значимое измерение. Вы можете запускать 10000, 100000 и т. Д. Раз, пока не получите «разумное количество миллисекунд».
Когда фрагмент кода, который вы тестируете, работает очень быстро, накладные расходы цикла могут стать значительными; в этом случае вы можете запустить «пустой цикл» и вычесть два результата, чтобы получить «чистый» тайминг только внутренней части цикла.
Однако это редко нужно делать — чаще всего вы пытаетесь сравнивать разные алгоритмы, и пока накладные расходы цикла одинаковы, не имеет значения, что он существует — чем быстрее будет алгоритм все еще будет быстрее.
Еще одна мысль — и это очень важно: если вы сортируете вещи в первом проходе через цикл, и скорость вашего алгоритма зависит от того, отсортированы данные или нет, вы получите другой ответ для нескольких проходов, чем для одного прохода. Таким образом, вы должны убедиться, что вы используете одни и те же входные данные для каждого прохождения алгоритма. Это может означать, что вы не можете использовать сортировку на месте или скопировать несортированные данные обратно в массив «для сортировки» при каждом проходе алгоритма.
другой вариант: Eсть хорошая статья о высокой точности времени это объясняет использование clock_gettime()
функция, с ее различными вариантами и вкусами. В некоторых системах это позволит вам использовать измерения с более высоким разрешением. По-прежнему всегда полезно выполнять несколько прогонов или даже несколько прогонов из нескольких прогонов — так что вы можете вычислить статистику и, таким образом, получить доверительный интервал.
Если ваш компилятор поддерживает C ++ 11 с станд :: хроно, это лучший способ измерить время с высокой точностью; это кроссплатформенная и часть стандартной библиотеки.
#include <chrono>
#include <iostream>
#include <iomanip>
::std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
doWork();
::std::chrono::steady_clock::duration elapsedTime = ::std::chrono::steady_clock::now() - startTime;
std::cout << std::fixed << std::setprecision(9) << std::endl;
double duration = ::std::chrono::duration_cast< ::std::chrono::duration< double > >(elapsedTime).count();
std::cout << "Milliseconds: " << duration * 1000 << std::endl;
Чтобы использовать C ++ 11 в GCC, вы запускаете g++ -std=c++11 -o app main.cpp
, Для компилятора Visual Studio требуется 2012 или более поздняя версия, чтобы использовать Chrono.
Если вы используете c ++ 11:
std::chrono::high_resolution_clock
представляет часы с наименьшим периодом тиков, предоставленным реализацией.