Как я могу измерить скорость кода, написанного в Java?
Я планирующий разработать программное обеспечение, которое решит Судоку с помощью всего в настоящее время доступного AI и алгоритмов ML и сравнит время с простым методом "в лоб". Я должен измерить время каждого алгоритма, я хотел бы попросить предложения на том, каков лучший способ сделать это? Очень важный, программа должна быть полезной на любой машине независимо к мощности ЦП / память.
Спасибо.
Как было предложено другими, System.currentTimeMillis ()
неплохо, но обратите внимание на следующие предостережения:
System.currentTimeMillis ()
измеряет прошедшее физическое время («время настенных часов») , а не процессорное время. Если на машине работают другие приложения, ваш код получит меньше ЦП и его скорость уменьшится. Итак, скамейка только на простаивающих системах. System.currentTimeMillis ()
. System.currentTimeMillis ()
редко составляет 1 мс. Во многих системах точность не лучше 10 мс или даже больше. Кроме того, JVM иногда запускает сборщик мусора, вызывая заметные паузы.Я предлагаю вам организовать измерения в цикле и настаивать на выполнении хотя бы нескольких секунд. Это дает следующий код:
for (int i = 0; i < 10; i ++) {
runMethod();
}
int count = 10;
for (;;) {
long begin = System.currentTimeMillis();
for (int i = 0; i < count; i ++)
runMethod();
long end = System.currentTimeMillis();
if ((end - begin) < 10000) {
count *= 2;
continue;
}
reportElapsedTime((double)(end - begin) / count);
}
Как видите, есть первые десять «пустых» прогонов. Затем программа запускает метод в цикле столько раз, сколько необходимо, чтобы цикл длился не менее десяти секунд. Десяти секунд должно быть достаточно, чтобы сгладить работу ГХ и другие системные неточности. Когда я тестирую реализации хэш-функции, я использую две секунды, и хотя сама функция вообще не вызывает выделения памяти, я все равно получаю отклонения до 3%.
Это другой способ (с наносекундами)
long nanos = System.nanoTime();
// execute your stuff
long duration = System.nanoTime() - nanos;
int seconds = (int) (duration / 1000000000);
int milliseconds = (int) (duration / 1000000) % 1000;
int nanoseconds = (int) (duration % 1000000);
System.out.printf("%d seconds, %d milliseconds en %d nanoseconds\n", seconds, milliseconds, nanoseconds);
Наносекунды лишние, но приятные.
Я обычно использую
System.currentTimeMillis()
для вычисления дельт времени:
long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;
Имейте в виду, что в зависимости от используемой операционной системы точность функции может быть больше чем 1 миллисекунда (также десятая часть миллисекунды), поэтому вам придется настроить ее, чтобы она была полезна для анализа.
РЕДАКТИРОВАТЬ: есть также альтернатива сделать то же самое с System.nanoTime ()
, но у вас нет никакой гарантии, что точность будет составлять наносекунды.
Если вас интересует высокая точность ваших измерений, вам следует измерять время процессора, а не «время настенных часов». Таким образом, вы не будете измерять время, которое ОС тратит на что-то еще. Чтобы измерить это время, вы, возможно, можете посмотреть Тестирование времени процессора Java
Хотя все ответы здесь верны, я бы предположил, что измерение в реальном времени может не иметь полного отношения к вашей цели, заключающейся в сравнении и сопоставлении различных алгоритмы поиска, чтобы найти «лучшее». В этом случае гораздо проще подсчитать количество узлов , которые вы ищете.Хотя приятно также знать время выполнения, здесь много шума, поскольку каждый алгоритм может определенным образом воздействовать на ЦП / кеш / память / диск. Измеряя узлы, вы смотрите на самую важную меру того, насколько хорош алгоритм поиска, поскольку чем меньше узлов он ищет, тем быстрее он найдет ответ.