Java nanoTime не дает надежных результатов - PullRequest
0 голосов
/ 13 марта 2020

Я делаю проект, в котором мне нужно реализовать алгоритмы пузырьковой сортировки, шеллсортировки и быстрой сортировки в массиве из 999 случайных двойных чисел.

Мне нужно измерить время, необходимое для выполнения каждого алгоритма.

Я использую System.nanoTime () для измерения этого времени выполнения для каждого алгоритма. У меня есть 3 кнопки, по одной на каждый алгоритм. При нажатии на кнопку запускается таймер, вызывается функция, затем вызывается таймер завершения, и рассчитывается продолжительность с использованием времени начала и времени окончания. Затем продолжительность печатается на ярлыке в верхней части кнопки.

public double[] randomArray = SortAlg.getArray();

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        long startTimeBubble = System.nanoTime();
        SortAlg.bubble(randomArray);
        long endTimeBubble = System.nanoTime();
        long durationBubble = (endTimeBubble - startTimeBubble) / 1000000;
        bubbleTiempo.setText("bubble took " + durationBubble + " ms");
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        long startTimeShellSort = System.nanoTime();
        SortAlg.shellSort(randomArray);
        long endTimeShellSort = System.nanoTime();
        long durationShellSort = (endTimeShellSort - startTimeShellSort) / 1000000;
        shellSortTime.setText("ShellSort took " + durationShellSort + " ms");
    }                                        

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        long startTimeQuickSort = System.nanoTime();
        SortAlg.quickSort(randomArray, 0, randomArray.length - 1);
        long endTimeQuickSort = System.nanoTime();
        long durationQuickSort = (endTimeQuickSort - startTimeQuickSort) / 1000000;
        quickSortTime.setText("Quicksort took " + durationQuickSort + " ms");
    } 

Общие пояснения: 1-getArray () генерирует случайный массив из 999 действительных (двойных) чисел в диапазоне от 0 до 2000.

2-Ни один из методов алгоритма не возвращает массив, поэтому этот randomArray НЕ сохраняется как отсортированный, поэтому при каждом нажатии кнопки случайный массив, передаваемый в функцию, не сортируется.

3-Каждая кнопка имеет уникальный ярлык для отображения результатов.

4-То, что вы видите, - это класс GUI, который я создал с помощью редактора Netbeans GUI, часть кнопок. Main просто создает новый GUI фрейм и устанавливает его как видимый, а SortAlg содержит лог c для алгоритмов, которые я уже тестировал для работы.

Но у меня есть 2 проблемы: Я нажимаю кнопку более 1 раза, время уменьшается для каждого клика, пока в конечном итоге не станет 0, что не имеет смысла.

Кроме того, у меня изначально была ошибка вычисления, и я делил время, взятое на 100000 а не 1000000, но, как ни странно, это никогда не давало мне никаких ошибок. Когда я делю его на 1000000, хотя (что должно быть правильной операцией для преобразования ns в мс) я иногда получаю 0 мс времени выполнения, что опять же не имеет смысла.

Наконец, и я знаю, что это может быть трудно определить, но у меня сложилось впечатление, что быстрая сортировка должна была быть самым быстрым алгоритмом? Но время их выполнения сильно зависит от сборки. Иногда каждый из них составляет 5 мс, иногда его 30, а иногда 68. Я обеспокоен, потому что кажется, что первый клик всегда самый быстрый, а остальные в итоге медленнее. Я совсем не уверен в этих результатах.

1 Ответ

3 голосов
/ 13 марта 2020

Когда я делю его на 1000000, хотя (что должно быть правильной операцией для преобразования ns в мс), я иногда получаю 0 мс времени выполнения, что опять же не имеет смысла.

Потому что вы используете целочисленное деление:

long durationBubble = (endTimeBubble - startTimeBubble) / 1000000;
                                                          ^^^^^^^

Просто замените его на double, чтобы включить дробь:

double durationBubble = (endTimeBubble - startTimeBubble) / 1_000_000.0;

См .:

...