Цикл Java For vs while, странное поведение и производительность по времени - PullRequest
3 голосов
/ 18 ноября 2011

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

Итак, для цикла for, если условие ложно, оно продолжает повторяться с простыми изменениями переменных. При использовании цикла while с параметром условие as, в то время как цикл будет остановлен, если условие ложно, и должно сохранить некоторые итерации.

Однако цикл while остается немного медленнее цикла for!

Но, если я поставлю значение int в качестве счетчика и посчитаем итерации, цикл For, как и ожидалось, будет выполнять гораздо больше итераций. Однако на этот раз время выполнения метода mofified For со счетчиком будет намного медленнее, чем у метода while со счетчиком!

Есть объяснения?

здесь код с циклом for:

for (int i = pairs.length - 1; i >= 0; i -= 2) {
    //cpt++;
    u = pairs[i];
    v = pairs[i - 1];

    duv = bfsResult.distanceMatrix.getDistance(u, v);

    if (duv > delta) {
        execute();
    }
}

время исполнения: 6473
время выполнения со счетчиком: 8299
Всего итераций: 2584401

вот код с циклом while:

int i = pairs.length - 1;

u = pairs[i];
v = pairs[i - 1];

duv = bfsResult.distanceMatrix.getDistance(u, v);

while (duv > delta) {
    //cpt++;
    execute();

    u = pairs[i -= 2];
    v = pairs[i - 1];
    duv = bfsResult.distanceMatrix.getDistance(u, v);
}

время исполнения: 6632
время выполнения со счетчиком: 7163
число итераций: 9793

Время в мс, я повторил эксперимент несколько раз с разными размерами, меры остались практически неизменными. Метод execute () обновляет значение дельты. Метод getDistance () представляет собой просто матрицу int [] [] доступа.

Спасибо за любую помощь.

Ответы [ 3 ]

4 голосов
/ 18 ноября 2011

Прежде чем пытаться выполнить какие-либо тесты производительности на Java, я настоятельно рекомендую вам прочитать эту статью http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html

В двух словах - при работе в течение некоторого времени JVM с поддержкой Hotspot может оптимизировать ваш код, что повлияет на результаты тестов. Таким образом, вам нужна правильная техника для тестирования производительности вашего кода. Для облегчения боли есть библиотека, используемая для выполнения правильных тестов: http://ellipticgroup.com/html/benchmarkingArticle.html Вы можете найти ссылки на обе части статьи на этой странице.

Обновление: чтобы помочь вам быстрее начать, вот что вам нужно сделать:

  1. Загрузите bb.jar, jsci-core.jar, mt-13.jar на странице
  2. Положите их на путь к классу
  3. Переписать ваш код так, чтобы подходы цикла и для цикла подходили в отдельных реализациях интерфейса Runnable или Callable
  4. В вашем основном методе просто вызовите

System.out.println(new Benchmark(new WhileApproach()));

чтобы показать время выполнения цикла while и, очевидно,

System.out.println(new Benchmark(new ForApproach()));

чтобы получить информацию для цикла

1 голос
/ 18 ноября 2011

У вас нет такого же условия завершения. Для цикла while это:

duv > delta

а для цикла for

i >= 0

Два сценария не эквивалентны. Я предполагаю, что условие цикла while становится ложным намного раньше, чем условие for, и поэтому оно выполняет меньше итераций.

0 голосов
/ 18 ноября 2011

Когда duv>delta, цикл while останавливается, но цикл for продолжается.Оба получают одинаковый результат, но for продолжает проверку.Вы должны изменить цикл for следующим образом: if (duv > delta) { execute(); } else break;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...