Почему Java System.timeNano() показывает одно и то же время?

Я хочу протестировать время выполнения некоторого алгоритма сортировки со следующим кодом

int n = 2000;
for(int i=0; i<10; i++){
    n *= 2;
    init(array, n); // initializes array with n elements
    long startTime = System.nanoTime();
    sort(array;
    long elapsedTime = System.nanoTime()-startTime;
    System.out.println("Size: "+n+"\t\tTime: "+elapsedTime/1000000+"(ms)");         
}

Выход

Size: 4000      Time: 0(ms)
Size: 8000      Time: 0(ms)
Size: 16000     Time: 0(ms)
Size: 32000     Time: 0(ms)
Size: 64000     Time: 0(ms)
Size: 128000    Time: 0(ms)
Size: 256000    Time: 0(ms)
Size: 512000    Time: 0(ms)
Size: 1024000   Time: 0(ms)
Size: 2048000   Time: 0(ms)

Проблема не в алгоритме, он правильно сортирует массивы, а для работы с большими массивами требуется заметное время. Этот пример занял около 10 секунд. Я думаю, что использовал nanoTime() так же, как описано в документации по Java. Я искал ответ на эту проблему, и кажется, что люди сталкивались с подобной проблемой. Например, здесь Есть ли секундомер в Java?. Однако я не смог найти ответ, как решить проблему. Были предложения использовать StopWatch apache, но, насколько я понял, он использует аналогичные вызовы nanoTime(). Итак, как решить эту проблему? Если это имеет значение, я запускаю код в Windows 7 с jre 1.8.0_31. Спасибо


person Andy    schedule 02.06.2015    source источник
comment
Можете ли вы включить код для init?   -  person    schedule 02.06.2015
comment
sort(array; вообще компилируется? ;)   -  person Alejandro    schedule 02.06.2015
comment
@Toby и да, вы правы, мой метод инициализации неправильно инициализировал массивы :) Вот почему это было так быстро   -  person Andy    schedule 02.06.2015
comment
@ Энди, ты понимаешь, почему метод инициализации работает неправильно?   -  person    schedule 02.06.2015
comment
@Toby Да, я передавал массив и пытался инициализировать его внутри init() через array = new int[size]. Но в java аргументы передаются по значению, так что это не повлияло на мой исходный массив вне метода.   -  person Andy    schedule 02.06.2015
comment
@Энди Да, именно :-)   -  person    schedule 02.06.2015


Ответы (2)


Вы видите одно и то же число, потому что используете целочисленное деление для преобразования наносекунд в миллисекунды, что имеет эффект деления его, а затем усечения любых десятичных знаков.

Попробуйте изменить:

elapsedTime/1000000

to:

elapsedTime/1000000d

чтобы получить результат, включая десятичные знаки, чтобы вы получали дробные миллисекунды.

Вы также можете проверить синхронизацию цикла, заменив вызов sort на Thread.sleep(50); — вы должны увидеть, что каждая итерация цикла занимает чуть более 50 мс.

person 1337joe    schedule 02.06.2015
comment
Вы хотите сказать, что elapsedTime меньше, чем 1000000? - person Sotirios Delimanolis; 02.06.2015
comment
У меня нет вашего метода сортировки, поэтому я действительно не могу сказать, что вы получаете за elapsedTime, но если это так, вы всегда будете печатать 0. Вот почему я предложил поместить в цикл sleep - вы знаете, сколько времени займет сон, чтобы вы могли сверить с ним вывод своего таймера. - person 1337joe; 02.06.2015
comment
Спасибо, 1337joe. Похоже, что это округление до нуля действительно было проблемой. Хотя, я удивлена ​​результатом. Я использовал алгоритм сортировки QuickSort. И метод init() случайным образом инициализирует массив заданным размером. У меня тоже должны быть глупые ошибки в этих методах :) - person Andy; 02.06.2015

Что ж, похоже, что ответ просто в том, что алгоритм сортировки работает быстрее миллисекунды в каждом случае, и мое целочисленное деление округлило его до нуля. Прошу прощения за такую ​​глупость :)

Обновленный код

int n = 2000;
for(int i=0; i<10; i++){
    n *= 2;
    int maxN = 500;
    init(array, n, maxN);
    long startTime = System.nanoTime();
    sort(array, 0, array.length-1); 
    long endTime = System.nanoTime();
    int elapsedTime = (int) (endTime-startTime);
    System.out.println("Size: "+n+"\t\tTime: "+elapsedTime+"(ns)"+
                "\t\tStart Time: "+startTime+
                "\t\tEnd Time: "+endTime);          
}

показывает вывод

Size: 4000      Time: 15822(ns)     Start Time: 699563217433713     End Time: 699563217449535
Size: 8000      Time: 3849(ns)      Start Time: 699563218239780     End Time: 699563218243629
Size: 16000     Time: 4276(ns)      Start Time: 699563219213047     End Time: 699563219217323
Size: 32000     Time: 3421(ns)      Start Time: 699563220704592     End Time: 699563220708013
Size: 64000     Time: 9835(ns)      Start Time: 699563222929081     End Time: 699563222938916
Size: 128000        Time: 3849(ns)      Start Time: 699563227085137     End Time: 699563227088986
Size: 256000        Time: 3849(ns)      Start Time: 699563234049813     End Time: 699563234053662
Size: 512000        Time: 5987(ns)      Start Time: 699563247567366     End Time: 699563247573353
Size: 1024000       Time: 8980(ns)      Start Time: 699563274115410     End Time: 699563274124390
Size: 2048000       Time: 8125(ns)      Start Time: 699563326704767     End Time: 699563326712892
person Andy    schedule 02.06.2015