#java
#java
Вопрос:
Я выполнял некоторые тесты производительности алгоритма и заметил кое-что странное. Возможно, я здесь чего-то не хватает.
Сначала я измеряю время в миллисекундах:
long startTime = System.currentTimeMillis();
x.sort(sortStringInput);
long endTime = System.currentTimeMillis();
а затем в наносекунде:
long startTime = System.nanoTime();
x.sort(sortStringInput);
long endTime = System.nanoTime();
Результаты составляют 437 мс qnd 26366ns.
Я вызываю один и тот же метод, так как же можно получить результат в ns, который намного меньше, чем в ms. Я знаю, что 1 мс равен 1 000 000 нс, поэтому 26366 даже меньше, чем 1 мс…
Спасибо,
Комментарии:
1. Значения, которые вы получаете за такие короткие промежутки времени, ненадежны. Создайте цикл и выполните тест пару тысяч раз (если не больше!). Затем возьмите среднее значение, и вы увидите, что два результата будут близки. А также то, что сказал @Cameron Skinner.
2. Не хочу показаться грубым, но люди обычно плохо пишут бенчмаркинги на Java. Вам нужно будет показать свой тестовый жгут, чтобы мы могли грамотно прокомментировать. Такие вещи, как компиляция Hotspot, могут существенно повлиять на тесты, если вы просто запускаете их один раз. В идеале вы должны запускать их оба, один за другим (и множество итераций каждого сразу), много-много раз, прежде чем начнете доверять результатам. И тогда вы должны брать среднее значение, отбрасывая внешние результаты (часто из-за сборки мусора) и т.д.
3. Кстати, на какой платформе вы работаете?
System.nanoTime
обычно выдает ответы, кратные тысячам.
Ответ №1:
Вы сортируете один и тот же список дважды? Второй вызов будет чрезвычайно быстрым, если список уже отсортирован.
Комментарии:
1. Вы абсолютно правы… Как я могу сделать что-то подобное… Должен ли я удалить сообщение?
2. @user393381: Нет, не удаляйте это! Если у кого-то такая же проблема и он ищет ее в Google, он может найти помощь здесь.
3. @user: Также вам был дан правильный ответ, поэтому вы можете просто принять его, и он будет «закрыт» (в том смысле, что никто не попытается на него ответить)
4. Также обратите внимание, что при повторной сортировке списка, даже если он будет сброшен, весь код будет загружен и готов к работе.
Ответ №2:
В зависимости от того, на какой платформе вы работаете, System.nanoTime()
сам по себе может быть очень медленным. Вам лучше запустить тест несколько раз и измерить общую продолжительность в миллисекундах.
Комментарии:
1. Но они получают противоположный результат. Больше времени в ms, чем в ns
2. @dspyz Я это знаю. Смысл, который я подчеркиваю (плохо), заключается в том, что лучше измерять более длительное время (путем циклического тестирования) с помощью более детализированной единицы измерения, чем пытаться измерить очень короткий интервал, используя меру, которая не всегда ведет себя предсказуемо.
3. Хотя это верно, также ничего не стоит, что currentTimeMillis() и nanoTime() занимают одинаковое количество времени на некоторых платформах. Стоит следовать вашему предложению независимо от того, как вы измеряете время.
Ответ №3:
Я предлагаю вам запускать тест не менее 2 секунд, прежде чем подсчитывать какой-либо результат, а также выполнять тест не менее 2 секунд и получать среднее значение. Выводится следующий код.
Average sort time 116 ms.
Average sort time 117100526 ns.
Average sort time 116 ms.
Average sort time 116530255 ns.
Average sort time 117 ms.
Average sort time 116905977 ns.
Код
public static void main(String... args) throws IOException {
String[] strings = new String[100 * 1000];
for (int i = 0; i < strings.length; i )
strings[i] = "" Math.random();
int runTimeMS = 2000;
for (int i = 0; i <= 3; i ) {
{
long start = System.currentTimeMillis();
int count = 0;
do {
Arrays.sort(strings.clone());
count ;
} while (System.currentTimeMillis() - start < runTimeMS);
long time = System.currentTimeMillis() - start;
if (i>0) System.out.println("Average sort time " time / count " ms.");
}
{
long start = System.nanoTime();
int count = 0;
do {
Arrays.sort(strings.clone());
count ;
} while (System.nanoTime() - start < runTimeMS * 1000L * 1000L);
long time = System.nanoTime() - start;
if (i>0) System.out.println("Average sort time " time / count " ns.");
}
}
}