Как засекать время в java
Перейти к содержимому

Как засекать время в java

  • автор:

Как засечь время выполнения цикла или программы или какого-то оператора?

Author24 — интернет-сервис помощи студентам

Засечь время выполнения (в ms) определённого кода или части кода
Доброго времени суток всем. Хотелось бы поинтересоваться у знающих людей. Как можно засеч время.

Какой функцией можно засечь время выполнения программы
Здравствуйте. подскажите какой функцией можно засечь время выполнения программы и вывести его в.

Как запретить удаление Папки или Файла на время выполнения программы
Собственно сабж. Нужно запретить удаление папки, причем совершенно левой, как это сделать кто.

Как засечь время выполнения функции?
Упражнение 3.1 K&R как новичку без серьезных описаний и дополнений кода засечь время выполнения.

237 / 236 / 72
Регистрация: 02.07.2013
Сообщений: 881

1 2 3
long startTime = System.nanoTime(); // . the code being measured . long estimatedTime = System.nanoTime() - startTime;

Регистрация: 08.04.2013
Сообщений: 138
Wado-Ru, это в каких единицах измеряется?
237 / 236 / 72
Регистрация: 02.07.2013
Сообщений: 881

currentTimeMillis() Returns the current time in milliseconds.
nanoTime() Returns the current value of the most precise available system timer, in nanoseconds

это все из документации по ссылке
Регистрация: 28.04.2014
Сообщений: 31

К сожалению, считать время выполнения таких вещей очень и очень сложно. И, разумеется, одним currentTimeMillis() или nanoTime() здесь не отделаться.
Во-первых, вы знаете в каком режиме у вас будет работать метод в момент подсчета? Если в интерпретируемом режиме (выполнение байт-кода), то у вас будут одни цифры. Если в скомпилированном варианте (нативный код), то совсем другие. Если начнут компилироваться какие-то зависимые методы, то третьи. И т.д..
Во-вторых, а вы уверены, что ваш цикл реально будет выполнятся? Может быть в боевом окружении он работает, а в тестовом компилятор, проведя escape-analysis, его тупо игнорирует?
В-третьих, у самих методов получения времени есть свои погрешности. Например, на линуксах они порядка 30-50 наносекунд. На Виндах могут доходить до тысяч наносекунд. Это озаначает, что невозможо более-менее точно замерить что-то, что длиться меньше указанного времени (по аналогии с длиной волны света и разрешающей способности светового микроскопа).

К счастью, за нас уже побеспокоились об этом — JMH. На данные момент это единственный инструмент для достоверного проведения микробенчмарков. Но одного его недостаточно. Надо помнить про погрешности, про прогрев, про богус-фрагменты, и т.д.. JMH дает возможность легко ими управлять, но если вы про них не знаете, у вас все равно ничего не получится.

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Засечь время выполнения поиска
Создается массив случайных чисел, сортируется, и затем проводится поиск по этому массиву. Для.

Засечь время выполнения пирамидальной сортировки
мне нужно засечь время выполнения алгоритма сортировок, и у меня не выходит только с одной — с.

Нужно засечь время выполнения процедуры
писал вот код form1.timer.enabled:=true; search; form1.timer.enabled:=false;Код таймера.

Окно программы во время выполнения цикла
Пока выполняется цикл в программе окно становится не доступным. Ни свернуть не переместить и тд.

Или воспользуйтесь поиском по форуму:

Как замерить время выполнения

Зачастую требуется узнать, сколько времени выполняется тот или иной код. Иногда требуется замерить время выполнения метода или какой-то задачи. В данной статье мы расскажем вам принципы замера времени в Java и покажем лучшие практики для конкретных задач.

Замер времени с помощью currentTimeMills()

Это довольно простой способ измерить время. Метод System.currentTimeMillis() вернёт вам текущее время в миллисекундах. Его потребуется вызвать до выполнения нужной задачи и после, а затем вычислить разницу. В итоге мы узнаем время выполнения в миллисекундах:

long start = System.currentTimeMillis(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.currentTimeMillis(); long elapsed = finish - start; System.out.println("Прошло времени, мс: " + elapsed);

При работе с данным методом следует учитывать его специфику: System.currentTimeMillis() показывает текущее время, основываясь на системных часах и может выдавать некорректный результат.

Замер времени с помощью nanoTime()

Ещё один метод для получения текущего времени это System.nanoTime(). Как следует из названия, этот метод возвращает время с точностью до нансекунд. Также работа этого метода не зависит от системных часов.

Он используется аналогично:

long start = System.nanoTime(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.nanoTime(); long elapsed = finish - start; System.out.println("Прошло времени, нс: " + elapsed);

Для получения значения в миллисекундах результат можно разделить на 1000:

System.out.println("Прошло времени, мс: " + elapsed / 1000000);

Важно: Хотя метод nanoTime() может возвращать время в наносекундах, он не гарантирует, что значения между его вызовами будут обновляться с точностью до наносекунд.

Но всё же это более приемлемый вариант, чем System.currentTimeMillis().

Замер времени с помощью Instant и Duration

В Java 8 добавили новый java.time API. В частности, ля измерения времени подойдут два новых класса – Instant и Duration. Оба эти класса иммутабельны.

Instant обозначает момент времени с начала эпохи Unix (1970-01-01T00:00:00Z). Для создания момента мы используем метод Instant.now(). После того, как мы создали два момент, вычислим разницу в миллисекундах:

Instant start = Instant.now(); // выполнение какой-то логики Thread.sleep(1000); Instant finish = Instant.now(); long elapsed = Duration.between(start, finish).toMillis(); System.out.println("Прошло времени, мс: " + elapsed);

Рекомендуется использовать именно этот подход в Java 8 и выше.

Замер времени выполнения с помощью StopWatch

StopWatch – это класс из библиотеки Apache Commons Lang. Он работает как секундомер. Для его использования сначала требуется подключить библиотеку к проекту:

 org.apache.commons commons-lang3 3.9 

Теперь создадим экземпляр StopWatch. Затем начнём отсчёт с помощью метода start() и окончим отсчёт с помощью метода stop():

public static void stopWatch() throws InterruptedException < StopWatch stopWatch = new StopWatch(); stopWatch.start(); // выполнение какой-то логики Thread.sleep(1000); stopWatch.stop(); System.out.println("Прошло времени, мс: " + stopWatch.getTime()); >

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

Исходный код

package ru.javalessons.time; import org.apache.commons.lang3.time.StopWatch; import java.time.Duration; import java.time.Instant; public class MeasureElapsedTime < public static void main(String[] args) throws InterruptedException < currentTimeMillis(); nanoTime(); instant(); stopWatch(); >public static void currentTimeMillis() throws InterruptedException < long start = System.currentTimeMillis(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.currentTimeMillis(); long elapsed = finish - start; System.out.println("Прошло времени, мс: " + elapsed); >public static void nanoTime() throws InterruptedException < long start = System.nanoTime(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.nanoTime(); long elapsed = finish - start; System.out.println("Прошло времени, нс: " + elapsed); >public static void instant() throws InterruptedException < Instant start = Instant.now(); // выполнение какой-то логики Thread.sleep(1000); Instant finish = Instant.now(); long elapsed = Duration.between(start, finish).toMillis(); System.out.println("Прошло времени, мс: " + elapsed); >public static void stopWatch() throws InterruptedException < StopWatch stopWatch = new StopWatch(); stopWatch.start(); // выполнение какой-то логики Thread.sleep(1000); stopWatch.stop(); System.out.println("Прошло времени, мс: " + stopWatch.getTime()); >>

Заключение

В данной статье мы разобрали простые методы замера времени выполнения в Java. Для простых замеров можно использовать все вышеперечисленные методы, кроме currentTimeMillis (из-за того, что он зависит от системных часов).

Как замерить время выполнения

  • ← Как заменить пробелы между словами в строке
  • Как узнать версию OpenSSH →

Измерение времени выполнения метода в Java

Одной из распространенных задач в процессе разработки и оптимизации программ на Java является измерение времени выполнения определенного метода или блока кода. Это может потребоваться, например, при необходимости определить, какой из двух алгоритмов работает быстрее, или для определения узкого места в программе, замедляющего ее работу.

Существует несколько способов измерить время выполнения метода в Java.

Использование System.currentTimeMillis()

Самым простым подходом является использование метода System.currentTimeMillis() . Этот метод возвращает текущее время в миллисекундах. Можно вызвать этот метод до и после выполнения интересующего блока кода, а затем вычесть из второго значения первое, чтобы получить время выполнения кода.

long startTime = System.currentTimeMillis(); // блок кода, время выполнения которого нужно измерить long endTime = System.currentTimeMillis(); long timeElapsed = endTime - startTime;

Использование System.nanoTime()

Еще одним подходом является использование метода System.nanoTime() . Этот метод работает аналогично System.currentTimeMillis() , но возвращает время в наносекундах, что позволяет измерять более короткие промежутки времени.

long startTime = System.nanoTime(); // блок кода, время выполнения которого нужно измерить long endTime = System.nanoTime(); long timeElapsed = endTime - startTime;

Однако стоит учесть, что точность измерения времени методом System.nanoTime() может быть ниже, чем у System.currentTimeMillis() , особенно на многопроцессорных системах.

Важно понимать, что эти методы измеряют «стенное» время, то есть реальное время, прошедшее с начала до конца выполнения блока кода. Они не учитывают такие факторы, как загруженность CPU другими процессами, операции ввода/вывода и прочее. Если требуется более детальный анализ производительности, следует использовать профилировщики кода, такие как VisualVM или JProfiler.

Чернышев Егор. Блог

Как-то раз я занимался оптимизацией сложной операции, выполняемой на сервере, которая включала в себя несколько запросов к базе данных с последующей группировкой и сортировкой по определенным параметрам полученных данных. К сожалению, средствами SQL запросов обойтись не получилось, так как в конечной выборке участвовали данные полученные по веб-сервисам из внешних систем. Поэтому приходилось выполнять группировку и сортировку данных с помощью кода приложения.

Когда я запустил первый раз этот код на реальных данных, очевидно, все работало неприемлемо медленно и требовало оптимизации. С чего начинать оптимизацию? Правило Парето никто не отменял и оно гласит, что нужно начинать оптимизацию тех участков кода, выполнение которых занимает львиную долю времени выполнения операции. Возникла задача выяснить, какой из этапов крупной операции выполняется дольше остальных, и насколько дольше. Для этого необходимо «стоять с секундомером» и засекать начало и конец каждого этапа и результат выводить в лог. На момент решения данной задачи я обошелся собственным решением, в котором я запоминал System.currentTimeMillis() в промежуточные значения в локальных переменных. Затем происходил подсчет разниц времени вывод в лог описаний. У данного подхода я обнаружил существенные недостатки:

  1. Код сильно загрязнился. Локальные переменные заполонили код, и его стало читать очень сложно.
  2. Сложно исправлять/добавлять новую операцию, так как логика о подсчету времени размазана.

Но есть и плюс, только он на мой взгляд один: это гибкость и возможность написать то, что тебе нужно.

Мне такое решение не давало покоя и я решил сделать небольшой обзор инструментов подсчета времени в java.

Что рассмотрим

Поискав в интернете на эту тему, я решил остановиться на рассмотрении 3-х реализаций секнудомеров.

  • GUAVA Stopwatch.
  • Apache Commons Lang StopWatch.
  • Spring Framework StopWatch.

Сравнивать реализации секундомеров будем на одном и том же фрагменте кода, в котором выполняется длительная операция состоящая из набора меньших операций. Код исходного класса представлен ниже:

package ru.egrik.stopwatch; import java.util.Random; /** * Очень сложная составная операция. * * @author echernyshev * @since 12 авг. 2013 г. */ public class VeryDifficultOperation < /** * Точка входа в операцию */ public void execute() < step1(); step2(); compositeStep3(); >/** * Шаг 1 */ private void step1() < waitRandomDelay(); >/** * Шаг 2 */ private void step2() < waitRandomDelay(); >/** * Сложный составной шаг 3 */ private void compositeStep3() < step31(); step32(); step33(); >/** * Первая часть шага 3 */ private void step31() < waitRandomDelay(); >/** * Вторая часть шага 3 */ private void step32() < waitRandomDelay(); >/** * Первая часть шага 3 */ private void step33() < waitRandomDelay(); >private void waitRandomDelay() < Random rmd = new Random(); int randomDelay = rmd.nextInt(3000); try < Thread.sleep(randomDelay); >catch (InterruptedException e) < e.printStackTrace(); System.exit(1); >> public static void main(String[] args) < VeryDifficultOperation operation = new VeryDifficultOperation(); operation.execute(); >> 

GUAVA

Для сборки проектов я использую Maven. Чтобы включить Guava в проект пропишем зависимость в pom.xml:

 com.google.guava guava 19.0 

Секундомер реализован в классе com.google.common.base. . Это самый простой секундомер из трех рассматриваемых. В нем есть 3 основных метода для управления:

  • start() — старт секундомера;
  • stop() — остановка секундомера;
  • reset() — сброс секундомера.
  • elapsed(TimeUnit u) — получить прошедшее время в java.util.concurrent.TimeUnit единицах.
  • toString() — получить строковое представление.
package ru.egrik.stopwatch; import java.util.Random; import java.util.concurrent.TimeUnit; import com.google.common.base.Stopwatch; /** * Очень сложная составная операция. * * @author echernyshev * @since 12 авг. 2013 г. */ public class VeryDifficultOperationGuavaStopwatch < /** * Точка входа в операцию */ public void execute() < Stopwatch sw = Stopwatch.createUnstarted(); System.out.println("Start Step1 at " + sw); sw.start(); step1(); long step1Elapsed = sw.elapsed(TimeUnit.MILLISECONDS); System.out.println("Step1 completed for " + step1Elapsed + "ms"); System.out.println("Start Step2 at " + sw); step2(); long step2Elapsed = sw.elapsed(TimeUnit.MILLISECONDS) - step1Elapsed; System.out.println("Step2 completed for " + step2Elapsed + "ms"); System.out.println("Start Step3 at " + sw); compositeStep3(sw); sw.stop(); long operationElapsed = sw.elapsed(TimeUnit.MILLISECONDS); long step3Elapsed = sw.elapsed(TimeUnit.MILLISECONDS) - step2Elapsed; System.out.println("Step3 completed for " + step3Elapsed + "ms"); StringBuffer summary = new StringBuffer("===\nOperation summary:\n") .append("Operation completed for " + operationElapsed + "ms\n") .append("Step1 for " + step1Elapsed + "ms ["+ String.format("%.2f", step1Elapsed / (double) operationElapsed * 100) + "%]\n") .append("Step2 for " + step2Elapsed + "ms ["+ String.format("%.2f", step2Elapsed / (double) operationElapsed * 100) + "%]\n") .append("Step3 for " + step3Elapsed + "ms ["+ String.format("%.2f", step3Elapsed / (double) operationElapsed * 100) + "%]\n") .append("==="); System.out.println(summary.toString()); >/** * Шаг 1 */ private void step1() < waitRandomDelay(); >/** * Шаг 2 */ private void step2() < waitRandomDelay(); >/** * Сложный составной шаг 3 */ private void compositeStep3(Stopwatch sw) < System.out.println("Start Step31 at " + sw); long before = sw.elapsed(TimeUnit.MILLISECONDS); step31(); long step31Elapsed = sw.elapsed(TimeUnit.MILLISECONDS) - before; System.out.println("Step31 completed for " + step31Elapsed + "ms"); System.out.println("Start Step32 at " + sw); step32(); long step32Elapsed = sw.elapsed(TimeUnit.MILLISECONDS) - before; System.out.println("Step32 completed for " + step32Elapsed + "ms"); System.out.println("Start Step33 at " + sw); step33(); long step33Elapsed = sw.elapsed(TimeUnit.MILLISECONDS) - before; System.out.println("Step33 completed for " + step33Elapsed + "ms"); >/** * Первая часть шага 3 */ private void step31() < waitRandomDelay(); >/** * Вторая часть шага 3 */ private void step32() < waitRandomDelay(); >/** * Первая часть шага 3 */ private void step33() < waitRandomDelay(); >private void waitRandomDelay() < Random rmd = new Random(); int randomDelay = rmd.nextInt(3000); try < Thread.sleep(randomDelay); >catch (InterruptedException e) < e.printStackTrace(); System.exit(1); >> public static void main(String[] args) < VeryDifficultOperationGuavaStopwatch operation = new VeryDifficultOperationGuavaStopwatch(); operation.execute(); >> 

Вывод консоли:

Start Step1 at 0,000 ns Step1 completed for 1425ms Start Step2 at 1,425 s Step2 completed for 1021ms Start Step3 at 2,446 s Start step31 at 2,447 s step31 completed for 1468ms Start step32 at 3,915 s step32 completed for 4389ms Start step33 at 6,836 s step33 completed for 6175ms Step3 completed for 7600ms === Operation summary: Operation completed for 8621ms Step1 for 1425ms [16,53%] Step2 for 1021ms [11,84%] Step3 for 7600ms [88,16%] === 

Видим, что читаемость кода ухудшилась, не хватает инкапсуляции переменных, которые хранят в себе засечки времени каждого этапа. По сути этот код практически ничем не лучше кода, который я написал с засеканием времени через System.currentTimeMillis(). Еще один существенный недостаток — это то, что класс объявлен как final и его нельзя дописать под свои нужды. Из плюсов хочется отметить то, что время можно засекать с точностью до наносекунд. Остальные рассматриваемые секундомеры засекают время с точностью до милисекунды. Таким образом, GUAVA применим в случаях, когда операции выполняются быстрее одной милисекунды, и в простых случаях использования секундомеров, когда больше одного интервала засекать не нужно.

Apache Commons Lang

Чтобы включить Apache Commons Lang в проект пропишем зависимость в pom.xml:

 commons-lang commons-lang 2.6 

Секундомер реализован в классе org.apache.commons.lang.time. . Для старта секундомера нужно вызвать метод start(). После этого возможны следующие действия с секундомером:

  • split() — остановка секундомера для того, чтобы посмотреть сколько прошло времени, пока секундомер продолжает идти в фоне. Метод unsplit() — снимает эффект метода split(). С момента вызова unsplit() доступны для вызова снова три перечисленных действия.
  • suspend() — приостановка секундомера. Метод resume() возобновляет работу секундомера. Время между вызовами suspend() и resume() не учитывается. С момента вызова resume() доступны для вызова снова три перечисленных действия.
  • stop() — останавливает секундомер.
  • getTime() — получить прошедшее время в милисекундах.
  • toString() — получить строковое представление.

Далее представлен код тестового класса с использованием Apache :

package ru.egrik.stopwatch; import java.util.Random; import org.apache.commons.lang.time.StopWatch; /** * Очень сложная составная операция. * * @author echernyshev * @since 12 авг. 2013 г. */ public class VeryDifficultOperationApacheStopWatch < /** * Точка входа в операцию */ public void execute() < StopWatchsw = new StopWatch(); System.out.println("Start Step1 at " + sw); sw.start(); step1(); sw.split(); long step1Elapsed = sw.getSplitTime(); System.out.println("Step1 completed for " + step1Elapsed + "ms"); System.out.println("Start Step2 at " + sw); sw.unsplit(); step2(); sw.split(); long step2Elapsed = sw.getSplitTime() - step1Elapsed; System.out.println("Step2 completed for " + step2Elapsed + "ms"); System.out.println("Start Step3 at " + sw); sw.unsplit(); compositeStep3(sw); sw.stop(); long operationElapsed = sw.getTime(); long step3Elapsed = sw.getTime() - step2Elapsed; System.out.println("Step3 completed for " + step3Elapsed + "ms"); StringBuffer summary = new StringBuffer("===\nOperation summary:\n") .append("Operation completed for " + operationElapsed + "ms\n") .append("Step1 for " + step1Elapsed + "ms ["+ String.format("%.2f", step1Elapsed / (double) operationElapsed * 100) + "%]\n") .append("Step2 for " + step2Elapsed + "ms ["+ String.format("%.2f", step2Elapsed / (double) operationElapsed * 100) + "%]\n") .append("Step3 for " + step3Elapsed + "ms ["+ String.format("%.2f", step3Elapsed / (double) operationElapsed * 100) + "%]\n") .append("==="); System.out.println(summary.toString()); >/** * Шаг 1 */ private void step1() < waitRandomDelay(); >/** * Шаг 2 */ private void step2() < waitRandomDelay(); >/** * Сложный составной шаг 3 */ private void compositeStep3(StopWatch sw) < System.out.println("Start Step31 at " + sw); long before = sw.getTime(); step31(); sw.split(); long step31Elapsed = sw.getSplitTime() - before; System.out.println("Step31 completed for " + step31Elapsed + "ms"); System.out.println("Start Step32 at " + sw); sw.unsplit(); step32(); sw.split(); long step32Elapsed = sw.getSplitTime() - before; System.out.println("Step32 completed for " + step32Elapsed + "ms"); System.out.println("Start Step33 at " + sw); sw.unsplit(); step33(); sw.split(); long step33Elapsed = sw.getSplitTime() - before; System.out.println("Step33 completed for " + step33Elapsed + "ms"); >/** * Первая часть шага 3 */ private void step31() < waitRandomDelay(); >/** * Вторая часть шага 3 */ private void step32() < waitRandomDelay(); >/** * Первая часть шага 3 */ private void step33() < waitRandomDelay(); >private void waitRandomDelay() < Random rmd = new Random(); int randomDelay = rmd.nextInt(3000); try < Thread.sleep(randomDelay); >catch (InterruptedException e) < e.printStackTrace(); System.exit(1); >> public static void main(String[] args) < VeryDifficultOperationApacheStopWatch operation = new VeryDifficultOperationApacheStopWatch(); operation.execute(); >> 

Вывод консоли:

Start Step1 at 0:00:00.000 Step1 completed for 2236ms Start Step2 at 0:00:02.236 Step2 completed for 2961ms Start Step3 at 0:00:05.197 Start Step31 at 0:00:05.197 Step31 completed for 850ms Start Step32 at 0:00:06.047 Step32 completed for 2205ms Start Step33 at 0:00:07.402 Step33 completed for 4517ms Step3 completed for 6753ms === Operation summary: Operation completed for 9714ms Step1 for 2236ms [23,02%] Step2 for 2961ms [30,48%] Step3 for 6753ms [69,52%] ===

Таким образом, Apache Commons Lang практически такой-же как и GUAVA , Единственное отличие — это наличие методов split() и unsplit(). Сколько я не думал, я не понял зачем нужны эти методы. Так как мы можем всегда взять текущее время секундомера через метод getTime() зачем его останавливать мне не понятно. Возможно это сделано для того, чтобы мы могли зафикировать конец операции в одном месте, а использовать getSplitTime намного позже. В моей задаче это приемущество не использовалось. Из плюсов отмечу то, что можно написать наследника данного класса доопределив в нем нужный функционал.

Spring Framework

Если вдруг так получилось, что в проекте над которым Вы работаете используется Spring, то Вы можете использовать реализацию секундомера из библиотеки spring-core. Подключаем через maven зависимость:

 org.springframework spring-core 4.0.6.RELEASE 

Секундомер реализован в классе org.springframework.util. . Основной фишкой данного секундомера является поддержка задач с именами и хранения списка задач на протяжении всего времени работы секундомера. Для управления секундомером есть 2 метода:

  • start(String taskName) — старт задачи с определенным именем.
  • stop() — остановка текущей задачи. Во время остановки — запоминается время, которое выполнялась задача.

Для вывода состояний секундомера есть 3 способа:

  • shortSummary() — краткая информация о текущем времени.
  • toString() — shortSummary() + имена всех задач с их временем выполнения и процентом от общего времени.
  • prettyPrint() — shortSummary() + красивый вывод таблицы с задачами, их временем выполнения, и процентом от общего времени.

Далее представлен код тестового класса с использованием Spring :

package ru.egrik.stopwatch; import java.util.Random; import org.springframework.util.StopWatch /** * Очень сложная составная операция. * * @author echernyshev * @since 12 авг. 2013 г. */ public class VeryDifficultOperationSpringStopWatch < /** * Точка входа в операцию */ public void execute() < StopWatch sw = createStopWatch("VeryDifficultOperation"); sw.start("Step1"); System.out.println(sw.shortSummary()); step1(); sw.stop(); sw.start("Step2"); System.out.println(sw.shortSummary()); step2(); sw.stop(); compositeStep3(sw); System.out.println(sw.prettyPrint()); >/** * Шаг 1 */ private void step1() < waitRandomDelay(); >/** * Шаг 2 */ private void step2() < waitRandomDelay(); >/** * Сложный составной шаг 3 */ private void compositeStep3(StopWatch sw) < sw.start("Step31"); System.out.println(sw.shortSummary()); step31(); sw.stop(); sw.start("Step32"); System.out.println(sw.shortSummary()); step32(); sw.stop(); sw.start("Step33"); System.out.println(sw.shortSummary()); step33(); sw.stop(); >/** * Первая часть шага 3 */ private void step31() < waitRandomDelay(); >/** * Вторая часть шага 3 */ private void step32() < waitRandomDelay(); >/** * Первая часть шага 3 */ private void step33() < waitRandomDelay(); >private void waitRandomDelay() < Random rmd = new Random(); int randomDelay = rmd.nextInt(3000); try < Thread.sleep(randomDelay); >catch (InterruptedException e) < e.printStackTrace(); System.exit(1); >> private StopWatch createStopWatch(String id) < return new StopWatch(id) < @Override public String shortSummary() < try < return super.shortSummary() + " LastTask: " + getLastTaskName() + " completed for " + getLastTaskTimeMillis() + "ms"; >catch (IllegalStateException e) < return super.shortSummary(); >> >; > public static void main(String[] args) < VeryDifficultOperationSpringStopWatch operation = new VeryDifficultOperationSpringStopWatch(); operation.execute(); >>

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

Вывод консоли:

StopWatch 'VeryDifficultOperation': running time (millis) = 0 StopWatch 'VeryDifficultOperation': running time (millis) = 2886 LastTask: Step1 completed for 2886ms StopWatch 'VeryDifficultOperation': running time (millis) = 2968 LastTask: Step2 completed for 82ms StopWatch 'VeryDifficultOperation': running time (millis) = 3933 LastTask: Step31 completed for 965ms StopWatch 'VeryDifficultOperation': running time (millis) = 5028 LastTask: Step32 completed for 1095ms StopWatch 'VeryDifficultOperation': running time (millis) = 6636 LastTask: Step33 completed for 1608ms ----------------------------------------- ms % Task name ----------------------------------------- 02886 043% Step1 00082 001% Step2 00965 015% Step31 01095 017% Step32 01608 024% Step33

Таким образом, получили достаточно лаконичный код и красивый вывод в консоль информации практически из коробки. Думаю, что для решения моей задачи Spring StopWatch подошел бы лучше всего. Жаль что его не было в проекте.

Выводы

Кратко охарактеризую каждый из рассмотренных секундомеров:

  1. GUAVA Stopwatch — быстрый, простой, точный.
  2. Apache Commons Lang Stopwatch — простой, немного нелогичный.
  3. Spring StopWatch — многоэтапный, с хорошим выводом состояний.

Спасибо за внимание, жду комментариев!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *