Как я могу измерить скорость кода, написанного на Java? (алгоритмы ИИ)

Как измерить скорость кода, написанного на Java?

Я планирую разработать программное обеспечение, которое будет решать судоку, используя все доступные в настоящее время алгоритмы искусственного интеллекта и машинного обучения, и сравнивать время с простым методом грубой силы. Мне нужно измерить время каждого алгоритма, я хотел бы попросить совета о том, как лучше всего это сделать? Очень важно, программа должна быть полезной на любой машине, независимо от мощности процессора/памяти.

Спасибо.


person Registered User    schedule 08.03.2010    source источник
comment
Не имеет отношения к основному вопросу, но может представлять интерес, учитывая, что вы планируете написать программное обеспечение для решения судоку. Взгляните на решение Norvig. norvig.com/sudoku.html   -  person hashable    schedule 15.03.2010
comment
+1 спасибо, да, я знаю это решение - хороший материал   -  person Registered User    schedule 15.03.2010


Ответы (5)


Как предполагают другие, System.currentTimeMillis() довольно хорош, но обратите внимание на следующие предостережения:

  • System.currentTimeMillis() измеряет прошедшее физическое время («время настенных часов»), а не процессорное время. Если на машине запущены другие приложения, ваш код получит меньше ресурсов ЦП и его скорость снизится. Таким образом, выполняйте бенч только на бездействующих системах.
  • Точно так же многопоточное приложение в многоядерной системе может получить дополнительный скрытый процессор. Измерение затраченного времени не отражает всей сложности многопоточных приложений.
  • Java нужно немного «разогреть». Виртуальная машина сначала интерпретирует код (что медленно), и, если данный метод используется слишком много раз, компилятор JIT преобразует метод в собственный код. Только в этот момент метод достигнет максимальной скорости. Я рекомендую вам выполнить несколько "пустых циклов" перед вызовом 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);
}

Как видите, есть первые десять "пустых" прогонов. Затем программа запускает метод в цикле столько раз, сколько необходимо, чтобы цикл занимал не менее десяти секунд. Десяти секунд должно быть достаточно, чтобы сгладить прогоны GC и другие системные неточности. Когда я тестирую реализацию хеш-функции, я использую две секунды, и хотя сама функция вообще не запускает выделение памяти, я все равно получаю вариации до 3%.

person Thomas Pornin    schedule 08.03.2010

я обычно использую

System.currentTimeMillis()

для расчета дельты времени:

long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;

Имейте в виду, что в зависимости от операционной системы, которую вы используете, точность функции может быть больше 1 миллисекунды (также десятой доли мс), поэтому вам придется настроить ее, чтобы она была полезна для вашего анализа.

РЕДАКТИРОВАТЬ: есть также альтернатива делать то же самое с System.nanoTime(), но у вас нет никакой гарантии, что точность будет равна наносекундам.

person Jack    schedule 08.03.2010

Это другой способ (с наносекундами)

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);

Нано дополнительные, но приятные.

person Martijn Courteaux    schedule 08.03.2010
comment
На большинстве машин нано не имеет смысла. - person Jonathon Faust; 08.03.2010

Если вы заинтересованы в высокой точности своих измерений, вам следует измерять время процессора, а не «время настенных часов». Таким образом, вы не будете измерять время, которое ОС тратит на что-то еще. Чтобы измерить это время, вы, возможно, можете взглянуть на тестирование процессорного времени Java.

person Thirler    schedule 08.03.2010

Хотя все ответы здесь действительны, я бы предположил, что измерение в реальном времени может быть не совсем уместным для вашей цели, которая состоит в том, чтобы сравнивать и сопоставлять различные алгоритмы поиска, чтобы найти «лучший». В этом случае гораздо проще подсчитать количество узлов, которые вы ищете. Хотя полезно также знать время выполнения, возникает много шума, поскольку каждый алгоритм может по-своему воздействовать на ЦП/кэш/память/диск. Измеряя узлы, вы смотрите на единственную наиболее важную меру того, насколько хорош алгоритм поиска, поскольку чем меньше узлов он ищет, тем быстрее он находит ответ.

person Shaggy Frog    schedule 10.03.2010