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

Обновлено: 02.07.2024

Большинство запросов в Google возвращают результаты для таймеров, которые планируют потоки и задачи, а это не то, что мне нужно.

Возможно, вы также захотите взглянуть на класс Apache Commons Lang StopWatch . Простой, но полезный служебный класс.

Всегда есть старомодный способ:

на самом деле, это «модно», потому что вы использовали nanoTime, который не был добавлен до java5 Это (или использование System.currentTimeMillis ()) похоже на то, как это обычно делается в Java . что я видел в любом случае. Меня все еще слегка удивляет отсутствие встроенного класса, такого как Timer t = new Timer (); String s = t.getElapsed (format); и т. д. Нет необходимости в блоке finally, так как endTime не будет использоваться, если выдается исключение.

Я иду с простым ответом. Работает для меня.

Это работает довольно хорошо. Разрешение очевидно только с точностью до миллисекунды, вы можете сделать лучше с System.nanoTime (). Есть некоторые ограничения для обоих (срезы расписания операционной системы и т. Д.), Но это работает довольно хорошо.

В среднем за пару пробежек (чем больше, тем лучше), и вы получите достойную идею.

На самом деле, System.currentTimeMillis () имеет точность только выше 15 мс. Для действительно низких значений нельзя доверять. Решением для этого (как уже упоминалось) является System.nanoTime (); Хорошо, я собирался принять это как официальный ответ, пока не прочитал комментарий Стива Дж. Отличный лакомый кусочек, Стив! nanoTime () не гарантирует точность лучше, чем currentTimeMillis, но многие реализации JVM имеют большую точность с nanoTime. Одним небольшим преимуществом currentTimeMillis является то, что это фактическая временная метка, и она также может быть использована для регистрации времени начала / окончания, тогда как nanoTime «может использоваться только для измерения прошедшего времени и не связана с каким-либо другим понятием системного или настенного времени. «.

Давайте, ребята! Никто не упомянул способ Гуавы сделать это (что, возможно, потрясающе):

Приятно то, что Stopwatch.toString () делает хорошую работу по выбору единиц времени для измерения. Т.е. если значение мало, оно выдаст 38 нс, если оно длинное, то покажет 5 м 3 с

Примечание: Google Guava требует Java 1.6+

К сожалению, секундомер Гуавы не является поточно-ориентированным. я научился этому нелегко. @DexterLegaspi Был бы очень заинтересован в вашем опыте! Заботиться, чтобы поделиться? Параллельное использование секундомера приведет к тому, что вы будете звонить start() несколько раз подряд (то же самое для stop() ).

Используя Instant и Duration из нового API Java 8,

Спасибо, Как я могу вывести результат, не имея ПТ впереди? @ java123999: Вы можете позвонить Duration.between(start, end).getSeconds() . Duration также есть методы для преобразования в другие единицы времени, например, toMillis() которые преобразуются в миллисекунды.

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

Удобочитаемый формат

Guava: Google Stopwatch JAR «Цель секундомера - измерить прошедшее время в наносекундах.

Apache Commons Lang JAR « StopWatch предоставляет удобный API для таймингов.

ДЖОДА- ВРЕМЯ

Java date time API из Java 8 «Объект Duration представляет период времени между двумя объектами Instant .

Spring Framework предоставляетслужебный класс StopWatch для измерения прошедшего времени в Java.

Секундомер Guava, Apache Commons и Spring Framework не являются поточно-ориентированными. Не безопасно для производственного использования. @DeepakPuthraya тогда какую библиотеку использовать, которая безопасна для производственного использования? @DeepakPuthraya вы можете использовать Java 8, предоставляемый API даты и времени Java. Что просто. IMO этот пост был бы полезен, если бы каждое решение также показывало результаты системных выходов.

Используйте профилировщик (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler и т. Д.). Вы получите самые точные результаты и наименее навязчивый. Они используют встроенный механизм JVM для профилирования, который также может дать вам дополнительную информацию, такую ​​как трассировки стека, пути выполнения и более полные результаты, если это необходимо.

При использовании полностью интегрированного профилировщика профилировать метод очень просто. Щелкните правой кнопкой мыши, Profiler -> Добавить к корневым методам. Затем запустите профилировщик так же, как вы выполняли тестовый прогон или отладчик.

Это было также отличным предложением, и одним из тех «скучных» моментов лампочки для меня, когда я читал этот ответ. Наш проект использует JDeveloper, но я проверил, и, конечно же, у него есть встроенный профилировщик! От java 7 build 40 (я думаю) они включали в себя бывший регистратор полетов JRockits до java (поиск Java Mission Control) Как получить выполнение метода в Java на Visual VM, например?

Это, вероятно, не то, что вы хотели, чтобы я сказал, но это хорошее использование АОП. Обведите прокси-перехватчик вокруг вашего метода и определите время там.

К сожалению, вопрос «что, почему и как» в АОП выходит за рамки этого ответа, но я бы так и сделал.

Изменить: Вот ссылка на Spring AOP, чтобы начать, если вы заинтересованы. Это самая доступная реализация AOP, которую Iive встретил для Java.

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

System.currentTimeMillis(); НЕ является хорошим подходом для измерения производительности ваших алгоритмов. Он измеряет общее время, которое вы испытываете, когда пользователь смотрит на экран компьютера. Он также включает время, затрачиваемое всем, что работает на вашем компьютере в фоновом режиме. Это может иметь огромное значение, если на вашей рабочей станции запущено много программ.

Правильный подход использует java.lang.management пакет.

  • «Время пользователя» - это время, потраченное на выполнение собственного кода вашего приложения.
  • «Системное время» - это время, потраченное на выполнение кода ОС от имени вашего приложения (например, для ввода-вывода).

getCpuTime() Метод дает вам сумму из них:

Это, безусловно, хороший момент, когда «время пользователя» (время настенных часов) не всегда является хорошим показателем производительности, особенно в многопоточной программе.

С Java 8 вы можете сделать что-то подобное с любыми обычными методами :

С помощью этого метода вы можете легко измерять время в любом месте кода, не нарушая его. В этом простом примере я просто печатаю время. Можете ли вы добавить переключатель для TimeIt, например, чтобы печатать только время в DebugMode или что-то еще.

Если вы работаете с Function, вы можете сделать что-то вроде этого:

Это выглядит намного лучше, чем другие решения. Это ближе к Spring AOP, но легче, чем это. Правда Java 8 способ! +1 Спасибо! Возможно, это выглядит хорошо для вас, потому что Стефан использует новые необычные функции Java. Но я думаю, что это трудно понять и понять.

Также мы можем использовать класс StopWatch Apache Commons для измерения времени.

Небольшой поворот, если вы не используете инструментарий и хотите использовать методы с малым временем выполнения: выполняйте его много раз, каждый раз удваивая число выполнений, пока не достигнете секунды, или около того. Таким образом, время обращения к System.nanoTime и т. Д., А также точность System.nanoTime не сильно влияют на результат.

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

Для этой цели мы используем аннотации AspectJ и Java. Если нам нужно узнать время выполнения метода, мы просто аннотируем его. Более продвинутая версия может использовать собственный уровень журнала, который можно включать и отключать во время выполнения.

К вашему сведению, JEP 230: Microbenchmark Suite является проектом OpenJDK для:

Добавьте базовый набор микробенчмарков в исходный код JDK и упростите разработчикам запуск существующих микробенчмарков и создание новых.

Эта функция появилась в Java 12 .

Для более ранних версий Java взгляните на проект Java Microbenchmark Harness (JMH), на котором основан JEP 230.

Действительно хороший код.

И чтобы добавить оставшиеся миллисы в конец, внесите следующие изменения: long millis = TimeUnit.MILLISECONDS.toMillis(duration) - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration)); if (days == 0) < res = String.format("%02d:%02d:%02d.%02d", hours, minutes, seconds, millis); >else < res = String.format("%dd%02d:%02d:%02d.%02d", days, hours, minutes, seconds, millis); >

Вы можете использовать Perf4j . Очень крутая утилита. Простое использование

Более подробную информацию можно найти в Руководстве разработчика

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

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

Если JIT решит скомпилировать его, ваши цифры будут сильно различаться. так что просто знайте

Используя AOP / AspectJ и @Loggable аннотации из jcabi-aspect, вы можете сделать это легко и компактно:

Spring предоставляет служебный класс org.springframework.util.StopWatch в соответствии с JavaDoc:

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

С аспектами:

Я написал метод для печати времени выполнения метода в удобочитаемой форме. Например, чтобы вычислить факториал в 1 миллион, потребуется приблизительно 9 минут. Таким образом, время выполнения печатается как:

Есть несколько способов сделать это. Я обычно использую что-то вроде этого:

или то же самое с System.nanoTime ();

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

И настроить его для вашей среды.

Методы могут быть аннотированы с помощью @Timed :

или кусок кода, завернутый с таймером :

Агрегированные метрики могут быть экспортированы в консоль, JMX, CSV или другие.

@Timed пример вывода метрик:

Если вы хотите настенные часы

Как сказал «skaffman», используйте AOP ИЛИ вы можете использовать время выполнения байт-кода, точно так же, как инструменты покрытия метода модульного теста используют для прозрачного добавления информации о синхронизации к вызываемым методам.

Если вам в конечном итоге удастся сделать то, что вы изложили, пожалуйста. поделитесь этим с сообществом здесь с вашей задачей / банками муравья.

Я изменил код из правильного ответа, чтобы получить результат в считанные секунды:

Вы можете использовать класс секундомера из основного проекта Spring:

Документация для секундомера: простой секундомер, позволяющий рассчитывать время выполнения ряда задач, показывая общее время выполнения и время выполнения для каждой названной задачи. Скрывает использование System.currentTimeMillis (), улучшая читабельность кода приложения и уменьшая вероятность ошибок вычислений. Обратите внимание, что этот объект не предназначен для работы с потоками и не использует синхронизацию. Этот класс обычно используется для проверки производительности во время проверки концепции и при разработке, а не как часть производственных приложений.

Вы можете попробовать этот способ, если просто хотите знать время.

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

Пример вывода на консоль:

В Java 8 представлен новый класс с именем Instant . Согласно документу:

Мгновенное представляет начало наносекунды на временной шкале. Этот класс полезен для генерации метки времени для представления машинного времени. Диапазон мгновенного требует хранения числа больше, чем long. Чтобы достичь этого, класс хранит длинную, представляющую эпоху-секунды, и int, представляющий наносекунду секунды, которая всегда будет между 0 и 999 999 999. Время в секундах измеряется из стандартной эпохи Java 1970-01-01T00: 00: 00Z, где моменты после эпохи имеют положительные значения, а более ранние моменты имеют отрицательные значения. Как для частей с эпохой, так и для наносекунды, большее значение всегда на временной шкале всегда позже, чем меньшее значение.

Ценим время с потоками - 1

Итак, предположим, что мы захотели набрать бутылку воды. В наличии имеются бутылка и кран с водой дяди Пети. Дяде Пете сегодня установили новый кран, и он без умолку нахваливал его красоту. До этого он пользовался только старым засорившимся краном, поэтому очереди на разливе были колоссальные. Немного повозившись, со стороны разлива послышался звук набирающейся воды, спустя 2 минуты бутылка все еще находится в стадии наполнения, за нами собралась привычная очередь, а в голове рисуется образ того, как заботливый дядя Петя отбирает только лучшие молекулы H2O в нашу бутылку. Обученный жизнью дядя Петя успокаивает особо агрессивных и обещает закончить как можно быстрее. Покончив с бутылкой, он берет следующую и включает привычный напор, не раскрывающий всех возможностей нового крана. Люди не довольны…

Теория

  • MIN_PRIORITY
  • NORM_PRIORITY (default)
  • MAX_PRIORITY
  • run() – выполняет поток
  • start() – запускает поток
  • getName() – возвращает имя потока
  • setName() – задает имя потока
  • wait() – наследуемый метод, поток ожидает вызова метода notify() из другого потока
  • notify() – наследуемый метод, возобновляет ранее остановленный поток
  • notifyAll() – наследуемый метод, возобновляет ранее остановленные потоки
  • sleep() – приостанавливает поток на заданное время
  • join() – ждет завершения потока
  • interrupt() – прерывает выполнение потока
  • Доступ к сети
  • Доступ к файловой системе
  • GUI

Класс Thread

Потоки в Java представлены в виде класса Thread и его наследников. Приведенный ниже пример является простейшей реализацией потокового класса. В результате получим Здесь мы создаем наш класс и делаем его наследником класса Thread , после чего пишем метод main() для запуска основного потока и переопределяем метод run() класса Thread . Теперь создав экземпляр нашего класса и выполнив его унаследованный метод start() мы запустим новый поток, в котором выполнится все что описано в теле метода run() . Звучит сложно, но взглянув на код примера все должно быть понятно.

Интерфейс Runnable

Oracle также предлагает для запуска нового потока реализовывать интерфейс Runnable , что дает нам большую гибкость в разработке, чем единственное доступное наследование в предыдущем примере (если заглянуть в исходники класса Thread можно увидеть, что он также реализует интерфейс Runnable ). Применим рекомендуемый метод создания нового потока. В результате получим Примеры очень похожи, т.к. при написании кода нам пришлось реализовать абстрактный метод run() , описанный в интерфейсе Runnable . Запуск же нового потока немного отличается. Мы создали экземпляр класса Thread , передав в качестве параметра ссылку на экземпляр нашей реализации интерфейса Runnable . Именно такой подход позволяет создавать новые потоки без прямого наследования класса Thread .

Долгие операции

Следующий пример наглядно покажет преимущества использования нескольких потоков. Допустим у нас есть простая задача, требующая нескольких длительных вычислений, до этой статьи мы решали бы ее в методе main() возможно разбив для удобства восприятия на отдельные методы, может быть даже классы, но суть была бы одна. Все операции совершались бы последовательно одна за другой. Давайте смоделируем тяжеловесные вычисления и замерим время их выполнения. В результате получим Время выполнения оставляет желать лучшего, а мы все это время смотрим на пустой экран вывода, и ситуация очень смахивает на историю про дядю Петю только теперь в его роли мы, разработчики, не воспользовавшиеся всеми возможностями современных устройств. Будем исправляться. В результате получим Время работы значительно сократилось (этот эффект может быть не достигнут или и вовсе увеличить время выполнения на процессорах не поддерживающих многопоточность). Стоит заметить, что потоки могут завершатся не по порядку, и если разработчику необходима предсказуемость действий он должен реализовать ее самостоятельно под конкретный случай.

Группы потоков

Потоки в Java можно объединять в группы, для этого используется класс ThreadGroup . В состав групп могут входить как одиночные потоки, так и целые группы. Это может оказаться удобным если вам надо прервать потоки связанные, например, с сетью при обрыве соединения. Подробнее о группах можно почитать здесь Надеюсь теперь тема стала вам более понятной и ваши пользователи будут довольны.

Во многих проектах требуется посчитать время, которое затратил тот или иной метод. Для этого можно вручную сохранять значение System.currentTimeMillis() и после метода вычислять затраченное время. Когда методов много это становится не очень удобным.
Поэтому я решил написать простенькую аннотацию, которая бы считала время выполнения метода. Попытавшись найти информацию в интернете, понял, что её по данной теме очень мало. Придётся как-то выкручиваться, собирая информацию по крупицам.

Наша аннотация будет помечать методы, для которых мы хотим посчитать время выполнения в миллисекундах или наносекундах и выводить результат через System.out.println.

Для начала создадим саму аннотацию:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target()
@Retention(RetentionPolicy.SOURCE)
public @ interface Time public enum TimeInterval < MILLISECOND, NANOSECOND >;
annotations.time.Time.TimeInterval interval() default annotations.time.Time.TimeInterval.MILLISECOND;
String format() default "Elapsed %s" ;
>

* This source code was highlighted with Source Code Highlighter .

Поле interval служит для указания интервала времени (миллисекунды или наносекунды), поле format задаёт формат вывода результата.

Теперь, чтобы данная аннотация сработала как надо, нужно создать класс-обработчик расширяющий AbstractProcessor. В данном классе добавляется сохранение времени перед кодом метода, сам код метода копируется в блок try-finally, а блоке finally вычисляется затраченное методом время и выводится в консоль:

import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.TypeTags;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCCatch;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util. List ;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

@SupportedAnnotationTypes( value = )
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class TimeAnnotationProcessor extends AbstractProcessor

public static final String ANNOTATION_TYPE = "annotations.time.Time" ;
private JavacProcessingEnvironment javacProcessingEnv;
private TreeMaker maker;

@Override
public void init(ProcessingEnvironment procEnv) super.init(procEnv);
this .javacProcessingEnv = (JavacProcessingEnvironment) procEnv;
this .maker = TreeMaker.instance(javacProcessingEnv.getContext());
>

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) if (annotations == null || annotations.isEmpty()) return false ;
>

final Elements elements = javacProcessingEnv.getElementUtils();

final TypeElement annotation = elements.getTypeElement(ANNOTATION_TYPE);

if (annotation != null ) // Выбираем все элементы, у которых стоит наша аннотация
final Set<? extends Element> methods = roundEnv.getElementsAnnotatedWith(annotation);

JavacElements utils = javacProcessingEnv.getElementUtils();
for (final Element m : methods) Time time = m.getAnnotation(Time. class );
if (time != null ) JCTree blockNode = utils.getTree(m);
// Нам нужны только описания методов
if (blockNode instanceof JCMethodDecl) // Получаем содержимое метода
final List <JCStatement> statements = ((JCMethodDecl) blockNode).body.stats;

// Новое тело метода
List <JCStatement> newStatements = List .nil();
// Добавляем в начало метода сохранение текущего времени
JCVariableDecl var = makeTimeStartVar(maker, utils, time);
newStatements = newStatements.append( var );

// Создаём тело блока try, копируем в него оригинальное содержимое метода
List <JCStatement> tryBlock = List .nil();
for (JCStatement statement : statements) tryBlock = tryBlock.append(statement);
>

// Создаём тело блока finally, добавляем в него вывод затраченного времени
JCBlock finalizer = makePrintBlock(maker, utils, time, var );
JCStatement stat = maker.Try(maker.Block(0, tryBlock), List .<JCCatch>nil(), finalizer);
newStatements = newStatements.append(stat);

// Заменяем старый код метода на новый
((JCMethodDecl) blockNode).body.stats = newStatements;
>
>
>

private JCExpression makeCurrentTime(TreeMaker maker, JavacElements utils, Time time) // Создаём вызов System.nanoTime или System.currentTimeMillis
JCExpression exp = maker.Ident(utils.getName( "System" ));
String methodName;
switch (time.interval()) case NANOSECOND:
methodName = "nanoTime" ;
break ;
default :
methodName = "currentTimeMillis" ;
break ;
>
exp = maker.Select(exp, utils.getName(methodName));
return maker.Apply( List .<JCExpression>nil(), exp, List .<JCExpression>nil());
>

protected JCVariableDecl makeTimeStartVar(TreeMaker maker, JavacElements utils, Time time) // Создаём финальную переменную для хранения времени старта. Имя переменной в виде time_start_
JCExpression currentTime = makeCurrentTime(maker, utils, time);
String fieldName = fieldName = "time_start_" + ( int ) ( Math .random() * 10000);
return maker.VarDef(maker.Modifiers(Flags.FINAL), utils.getName(fieldName), maker.TypeIdent(TypeTags.LONG), currentTime);
>

protected JCBlock makePrintBlock(TreeMaker maker, JavacElements utils, Time time, JCVariableDecl var ) // Создаём вызов System.out.println
JCExpression printlnExpression = maker.Ident(utils.getName( "System" ));
printlnExpression = maker.Select(printlnExpression, utils.getName( "out" ));
printlnExpression = maker.Select(printlnExpression, utils.getName( "println" ));

// Создаём блок вычисления затраченного времени (currentTime - startTime)
JCExpression currentTime = makeCurrentTime(maker, utils, time);
JCExpression elapsedTime = maker.Binary(JCTree.MINUS, currentTime, maker.Ident( var .name));

// Форматируем результат
JCExpression formatExpression = maker.Ident(utils.getName( "String" ));
formatExpression = maker.Select(formatExpression, utils.getName( "format" ));

// Собираем все кусочки вместе
List <JCExpression> formatArgs = List .nil();
formatArgs.append(maker.Literal(time.format()));
formatArgs.append(elapsedTime);

JCExpression format = maker.Apply( List .<JCExpression>nil(), formatExpression, formatArgs);

List <JCExpression> printlnArgs = List .nil();
printlnArgs.append(format);

JCExpression print = maker.Apply( List .<JCExpression>nil(), printlnExpression, printlnArgs);
JCExpressionStatement stmt = maker.Exec(print);

List <JCStatement> stmts = List .nil();
stmts.append(stmt);

return maker.Block(0, stmts);
>
>

* This source code was highlighted with Source Code Highlighter .

Для того чтобы компилятор java использовал наш управляющий класс, нужно создать файл META-INF/javax.annotation.processing.Processor, в котором должна быть прописана следующая строка:
annotations.time.TimeAnnotationProcessor

После этого собираем все наши файлы в annotations.jar и добавляем его в classpath к любому проекту.

Теперь, чтобы посчитать время выполнения метода, достаточно добавить к этому методу аннотацию Time и после его выполнения в консоль будет выведено затраченное методом время:

Как получить время выполнения метода? Есть ли класс утилиты таймера для таких вещей, как время, сколько времени занимает задача и т. д.?

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

Я иду с простым ответом. Работать на меня.

он работает довольно хорошо. Разрешение, очевидно, только до миллисекунды, вы можете сделать лучше с системой.nanoTime(). Существуют некоторые ограничения для обоих (срезы расписания операционной системы и т. д.) но это работает довольно хорошо.

среднее значение через пару прогонов (чем больше, тем лучше), и вы получите достойную идею.

ребята! Никто не упоминал гуавы способ сделать это (что, бесспорно, офигенно):

хорошая вещь, что секундомер.toString () выполняет хорошую работу по выбору единиц времени для измерения. Т. е. если значение мало, оно выведет 38 НС, если оно длинное, то оно покажет 5м 3С

Примечание: Google Guava требует Java 1.6+

используя МиГ и продолжительность из нового API Java 8,

используйте профилировщик (Jprofiler, Netbeans Profiler, Visual VM, Eclipse Profiler и т. д.). Вы получите наиболее точные результаты и наименее навязчивы. Они используют встроенный механизм JVM для профилирования, который также может дать вам дополнительную информацию, такую как трассировки стека, пути выполнения и более полные результаты, если это необходимо.

при использовании полностью интегрированного профилировщика, это faily тривиально профилировать метод. Щелкните правой кнопкой мыши, Profiler - > добавить в корневые методы. Запустите профайлер просто как будто вы делали тестовый запуск или отладчик.

собрали все возможные варианты в одном месте.

Удобочитаемом

Гуава: Google секундомер JAR " объектом секундомера является измеряет прошедшее время в наносекундах.

Apache Commons Lang JAR "секундомер предоставляет удобный API для таймингов.

Джодавремени

JAVA дата время API от Java 8 " A продолжительность

Это, вероятно, не то, что вы хотели, чтобы я сказал, но это хорошее использование AOP. Взбейте прокси-перехватчик вокруг вашего метода и сделайте время там.

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

Edit:вот ссылка Весна AOP, чтобы вы начали, если вы заинтересованы. Это самая доступная реализация AOP, с которой сталкивается Iive Ява.

кроме того, учитывая очень простые предложения всех остальных, я должен добавить, что AOP-это когда вы не хотите, чтобы такие вещи, как время, вторглись в ваш код. Но во многих случаях, такой простой и легкий подход-это нормально.

System.currentTimeMillis(); не является хорошим подходом для измерения производительности ваших алгоритмов. Он измеряет общее время, которое вы испытываете в качестве пользователя, наблюдающего за экраном компьютера. Он также включает в себя время, затрачиваемое на все остальное работает на вашем компьютере в фоновом режиме. Это может иметь огромное значение, если на вашей рабочей станции работает много программ.

правильный подход использует java.lang.management пакета.

  • "время" - это время, затраченное на выполнение кода приложения.
  • "системное время" - это время, затраченное на выполнение кода ОС от имени вашего приложения (например, для ввода-вывода).

getCpuTime() метод дает вам сумму тех:

С Java 8 вы также можете сделать что-то подобное с каждым нормальным методы:

С помощью этого methode вы можете легко измерять время в любом месте вашего кода, не нарушая его. В этом простом примере я просто печатаю время. Можете ли вы добавить переключатель для TimeIt, например, только для печати времени в DebugMode или что-то еще.

Если вы работаете с функции вы можете сделать что-то вроде это:

также мы можем использовать класс секундомера Apache commons Для измерения времени.

просто небольшой поворот, если вы не используете инструменты и хотите использовать методы с низким временем выполнения: выполняйте его много раз, каждый раз удваивая количество раз, пока не достигнете секунды или около того. Таким образом, время вызова системы.nanoTime и так далее, ни точность системы.nanoTime сильно влияет на результат.

конечно, предостережения об использовании настенных часов применяются: влияния JIT-компиляции, нескольких потоков / процессов и т. д. Таким образом, вы необходимо сначала выполнить метод большое раз сначала, так что компилятор JIT выполняет свою работу, а затем повторите этот тест несколько раз и возьмите наименьшее время выполнения.

для этой цели мы используем аннотации AspectJ и Java. Если нам нужно знать время выполнения метода, мы просто аннотируем его. Более продвинутая версия может использовать собственный уровень журнала, который может быть включен и отключен во время выполнения.

очень хороший код.

можно использовать Perf4j. Очень классная утилита. Использование просто

более подробную информацию можно найти в Руководство Разработчика

изменить: кажется, умер

использование AOP / AspectJ и @Loggable аннотации jcabi-аспекты вы можете сделать это легкий и компактный:

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

Если JIT решит скомпилировать его, ваши номера будут сильно отличаться. так что просто будьте в курсе

есть несколько способов сделать это. Обычно я возвращаюсь к использованию чего-то подобного:

или то же самое с системой.nanoTime();

Если вы хотите настенные часы время

Как сказал "skaffman", используйте AOP или вы можете использовать байт-код времени выполнения, так же, как инструменты покрытия метода модульного теста используют для прозрачного добавления информации о времени к вызываемым методам.

Если вам в конечном итоге удастся сделать то, что вы наметили, pls. поделитесь им с сообществом здесь с вашей задачей ant / jars.

Spring предоставляет служебный класс org.springframework.утиль.Секундомер, согласно JavaDoc:

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

С Аспектами:

Я изменил код с правильного ответа, чтобы получить результат в секундах:

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

пример вывода на консоль:

в Java 8 новый класс с именем это. Согласно doc:

Instant представляет собой начало наносекунды на временной линии. Этот класс полезен для создания метки времени для представления машинного времени. Диапазон мгновения требует хранения числа больше, чем a длинный. Для этого класс хранит длинное представление epoch-секунды и int, представляющий наносекунду секунды, которая будет всегда будет между 0 и 999 999 999. Этот epoch-измеряются секунды от стандартной эпохи Java 1970-01-01T00:00:00Z где мгновения после эпохи имеют положительные значения, а более ранние мгновения имеют отрицательное значение. Для эпох-второй и наносекундной частей a большее значение всегда является более поздним по времени, чем меньшее значение.

Это можно использовать как:

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

и настройте его для своей среды.

методы могут быть аннотированы с @Timed:

или кусок кода, обернутый таймер:

агрегированные метрики могут экспортироваться в консоль, JMX, CSV или другие.

@Timed пример вывода метрик:

System.nanoTime() - довольно точная системная утилита для измерения времени выполнения. Но будьте осторожны, если вы работаете в режиме упреждающего планировщика (по умолчанию), эта утилита фактически измеряет время настенных часов, а не время процессора. Таким образом можно заметить различные значения времени выполнения от запуска до запуска, в зависимости от загрузки системы. Если вы ищете время процессора, я думаю, что запуск вашей программы в режиме реального времени сделает трюк. Вы должны использовать RT linux. ссылка:программирование в реальном времени с В Linux

измерения производительности на моей машине

  • система.nanoTime() : 750ns
  • система.currentTimeMillis() : 18ns

Как уже упоминалось, система.считается, что nanoTime() измеряет прошедшее время. Просто имейте в виду стоимость, если используется insied цикл или тому подобное.

В этом уроке мы рассмотрим, как измерить время выполнения кода Java для проектов на базе Spring с помощью секундомера и его простого API.

Вступление

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

В многопоточных системах также полезно измерять время выполнения отдельных потоков с или асинхронных задач.

Поскольку в Java нет встроенного удобного способа измерения выполнения кода для решений на основе Spring, мы познакомились с инструментом Секундомер .

В этом уроке мы рассмотрим как измерить время выполнения кода на Java с помощью секундомера Spring .

Урок секундомера весны

Этот класс обычно используется для проверки производительности кода на этапе разработки, а не как часть производственных приложений.

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

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

Измерение времени выполнения кода с помощью секундомера

Секундомер принадлежит к ядру util пакета Spring:

Естественно, он также присутствует в spring-boot-starter-web зависимости:

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

Вы можете получить доступ к сумме всех задач через getTotalTimeSeconds() , getTotalTimeMillis() и getTotalTimeNanos() .

Вы также можете получить доступ к последней задаче секундомера через getLastTaskInfo() , которая возвращает экземпляр TaskInfo . Этот экземпляр содержит информацию о последней задаче, такую как имя и сколько времени это заняло в секундах, миллисекундах и наносекундах:

Теперь это приводит к:

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

При работе с несколькими задачами действительно удобным методом является метод prettyPrint () , который печатает все записи в виде таблицы с простым форматированием:

Вывод

Читайте также: