Як я можу виконати час виконання методу на Java?


834
  1. Як отримати час виконання методу?
  2. Чи існує Timerклас корисності для таких речей, як терміни, скільки часу займає завдання тощо?

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


JAMon API - це безкоштовний, простий, високопродуктивний, безпечний для потоків, Java API, який дозволяє розробникам легко контролювати продуктивність та масштабованість виробничих додатків. JAMon відстежує звернення, час виконання (загальний, сер, хв, макс, std dev) тощо. http://jamonapi.sourceforge.net/ завантажити: http://sourceforge.net/project/showfiles.php?group_id=96550
Майк Пойн

1
Можливо, ви також захочете переглянути клас стоп-годин Apache Commons Lang . Простий, але корисний клас корисності.


Так, StopWatch чудово підходить для цього.
Shubham Pandey

Java 8 , використовуючи Instantклас: stackoverflow.com/a/30975902/1216775
akhil_mittal

Відповіді:


1207

Завжди є старомодний спосіб:

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.

233
власне, його "новомодний", тому що ви використовували nanoTime, який не додавали до java5
Джон Гарднер

11
Це (або за допомогою System.currentTimeMillis ()) здається, як це зазвичай робиться на Яві ... що я бачив у будь-якому випадку. Це все ще м'яко мене дивує, що немає вбудованого класу, як Timer t = new Timer (); Рядок s = t.getElapsed (формат); тощо ...
Огр. Псалом33.

18
nanoTime не гарантує точність кращу, ніж currentTimeMillis (), хоча зазвичай це є. forums.sun.com/thread.jspa?messageID=9460663 та simongbrown.com/blog/2007/08/20/…
Джеймс

10
Звичайно, завжди важливо пам’ятати про підводні камені мікро-бенчмаркінгу, такі як оптимізація компілятора / JVM, які можуть спотворити результат = 8-)
Ювал,

18
Немає потреби в остаточному блоці, оскільки endTime не буде використовуватися, якщо буде викинуто виняток.
Пітер Лорі

197

Я йду з простою відповіддю. Працює для мене.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

Це працює досить добре. Роздільна здатність, очевидно, лише до мілісекунди, ви можете краще зробити з System.nanoTime (). Для обох є деякі обмеження (фрагменти графіку операційної системи тощо), але це працює досить добре.

Середня оцінка за пару пробіжок (чим більше, тим краще), і ви отримаєте гідне уявлення.


51
Насправді System.currentTimeMillis () точний лише понад 15 мс. Для дійсно низьких значень цьому не можна довіряти. Рішення для цього (як уже згадувалося) - System.nanoTime ();
Steve g

Гаразд, я збирався прийняти це як офіційну відповідь, поки не прочитав коментар Стіва g. Чудовий ласощі, Стів!
Псалом Огр33,

4
nanoTime () не гарантує точність кращу, ніж currentTimeMillis, але багато реалізацій JVM мають кращу точність з nanoTime.
Джеймс Шек

5
@JamesSchek Вам справді потрібно стежити за формулюванням, як я вже згадував цей ідентичний коментар деінде; nanoTimeгарантовано буде принаймні настільки ж рішучих як currentTimeMillis. docs.oracle.com/javase/7/docs/api/java/lang/…
b1nary.atr0phy

Одна незначна перевага currentTimeMillisполягає в тому, що це фактична мітка часу, і вона може бути використана також для реєстрації часу початку та закінчення, в той час як nanoTime"може використовуватися лише для вимірювання минулого часу і не пов'язане з будь-яким іншим поняттям системи або часу настінного годинника . "
Бред Паркс

177

Давайте, хлопці! Ніхто не згадав про спосіб Гуави зробити це (що, мабуть, приголомшливо):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

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

Ще приємніше:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

Примітка: Google Guava потрібна Java 1.6 або новіша версія


21
На жаль, секундомір Guava не є безпечним для потоків. Я навчився цього важким шляхом.
Декстер Легаспі

6
@DexterLegaspi Буде дуже зацікавлений у вашому досвіді! Хочете поділитися?
Сіддхартха

1
Паралельне використання секундоміра призводить до того, що ви дзвоните start()кілька разів поспіль (те саме для stop()).
Mingwei Samuel

141

Використовуючи миттєвий і тривалий час із нового API Java 8,

Instant start = Instant.now();
Thread.sleep(5000);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

виходи,

PT5S

2
Дякую, як я можу отримати результат, не маючи ПТ попереду?
java123999

1
Проблема методу полягає в тому, що миттєвий сигнал не має проблеми з точністю мілі та наносекунда. Посилання: stackoverflow.com/questions/20689055/…
prashantsunkari

8
@ java123999: Ви можете зателефонувати Duration.between(start, end).getSeconds(). Durationтакож є методи перетворення в інші одиниці часу, наприклад, toMillis()які перетворюються на мілісекунди.
Еміль Лунде

100

Зібрали всі можливі шляхи разом в одне місце.

Дата

Date startDate = Calendar.getInstance().getTime();
long d_StartTime = new Date().getTime();
Thread.sleep(1000 * 4);
Date endDate = Calendar.getInstance().getTime();
long d_endTime = new Date().getTime();
System.out.format("StartDate : %s, EndDate : %s \n", startDate, endDate);
System.out.format("Milli = %s, ( D_Start : %s, D_End : %s ) \n", (d_endTime - d_StartTime),d_StartTime, d_endTime);

Система. currentTimeMillis ()

long startTime = System.currentTimeMillis();
Thread.sleep(1000 * 4);
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);  
System.out.format("Milli = %s, ( S_Start : %s, S_End : %s ) \n", duration, startTime, endTime );
System.out.println("Human-Readable format : "+millisToShortDHMS( duration ) );

Людський читабельний формат

public static String millisToShortDHMS(long duration) {
    String res = "";    // java.util.concurrent.TimeUnit;
    long days       = TimeUnit.MILLISECONDS.toDays(duration);
    long hours      = TimeUnit.MILLISECONDS.toHours(duration) -
                      TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes    = TimeUnit.MILLISECONDS.toMinutes(duration) -
                      TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds    = TimeUnit.MILLISECONDS.toSeconds(duration) -
                      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    long millis     = TimeUnit.MILLISECONDS.toMillis(duration) - 
                      TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));

    if (days == 0)      res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
    else                res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
    return res;
}

Гуава: Секундомір Google JAR «Завдання секундоміра - це вимірювання минулого часу в наносекундах.

com.google.common.base.Stopwatch g_SW = Stopwatch.createUnstarted();
g_SW.start();
Thread.sleep(1000 * 4);
g_SW.stop();
System.out.println("Google StopWatch  : "+g_SW);

Apache Commons Lang JAR « StopWatch надає зручний API для синхронізації.

org.apache.commons.lang3.time.StopWatch sw = new StopWatch();
sw.start();     
Thread.sleep(1000 * 4);     
sw.stop();
System.out.println("Apache StopWatch  : "+ millisToShortDHMS(sw.getTime()) );

Joda -time

public static void jodaTime() throws InterruptedException, ParseException{
    java.text.SimpleDateFormat ms_SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    String start = ms_SDF.format( new Date() ); // java.util.Date

    Thread.sleep(10000);

    String end = ms_SDF.format( new Date() );       
    System.out.println("Start:"+start+"\t Stop:"+end);

    Date date_1 = ms_SDF.parse(start);
    Date date_2 = ms_SDF.parse(end);        
    Interval interval = new org.joda.time.Interval( date_1.getTime(), date_2.getTime() );
    Period period = interval.toPeriod(); //org.joda.time.Period

    System.out.format("%dY/%dM/%dD, %02d:%02d:%02d.%04d \n", 
        period.getYears(), period.getMonths(), period.getDays(),
        period.getHours(), period.getMinutes(), period.getSeconds(), period.getMillis());
}

API дати Java від Java 8 « Об'єкт тривалості представляє проміжок часу між двома миттєвими об’єктами.

Instant start = java.time.Instant.now();
    Thread.sleep(1000);
Instant end = java.time.Instant.now();
Duration between = java.time.Duration.between(start, end);
System.out.println( between ); // PT1.001S
System.out.format("%dD, %02d:%02d:%02d.%04d \n", between.toDays(),
        between.toHours(), between.toMinutes(), between.getSeconds(), between.toMillis()); // 0D, 00:00:01.1001 

Spring Framework забезпечуєклас утиліти StopWatch для вимірювання минулого часу на Java.

StopWatch sw = new org.springframework.util.StopWatch();
sw.start("Method-1"); // Start a named task
    Thread.sleep(500);
sw.stop();

sw.start("Method-2");
    Thread.sleep(300);
sw.stop();

sw.start("Method-3");
    Thread.sleep(200);
sw.stop();

System.out.println("Total time in milliseconds for all tasks :\n"+sw.getTotalTimeMillis());
System.out.println("Table describing all tasks performed :\n"+sw.prettyPrint());

System.out.format("Time taken by the last task : [%s]:[%d]", 
        sw.getLastTaskName(),sw.getLastTaskTimeMillis());

System.out.println("\n Array of the data for tasks performed « Task Name: Time Taken");
TaskInfo[] listofTasks = sw.getTaskInfo();
for (TaskInfo task : listofTasks) {
    System.out.format("[%s]:[%d]\n", 
            task.getTaskName(), task.getTimeMillis());
}

Вихід:

Total time in milliseconds for all tasks :
999
Table describing all tasks performed :
StopWatch '': running time (millis) = 999
-----------------------------------------
ms     %     Task name
-----------------------------------------
00500  050%  Method-1
00299  030%  Method-2
00200  020%  Method-3

Time taken by the last task : [Method-3]:[200]
 Array of the data for tasks performed « Task Name: Time Taken
[Method-1]:[500]
[Method-2]:[299]
[Method-3]:[200]

Секундомір Guava, Apache Commons та Spring Framework не є безпечними. Не безпечний для виробництва.
Діпак Путрая

@DeepakPuthraya, яку бібліотеку використовувати, яку безпечно використовувати для виробництва?
gaurav

1
@DeepakPuthraya ви можете використовувати API інтерфейсу Java для дати 8. Що просто.
Яш

IMO ця посада принесла б користь, якщо кожне рішення також показало б вихід із системи.
BAERUS

87

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

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


Це також було чудовою пропозицією, і один з тих "духа" моментів лампочки для мене, коли я читав цю відповідь. У нашому проекті використовується JDeveloper, але я перевірив, і досить впевнено, у нього є вбудований профілер!
Псалом Огр33,

2
Із java 7 build 40 (я думаю) вони включили колишній рекордер польоту JRockits до java (пошук управління Mission Java)
Niels Bech Nielsen

Впевнений, достатньо @NielsBechNielsen! oracle.com/technetwork/java/javaseproducts/mission-control/…
Огре Псалм33

Як отримати, наприклад, виконання методу на Java Visual VM?
okwap

41

Напевно, це не те, що ви хотіли, щоб я сказав, але це корисне використання АОП. Розмістіть проксі-перехоплювач навколо вашого методу і виконайте там часу.

Що, чому і як AOP, на жаль, виходить за рамки цієї відповіді, але, напевно, я б це зробив.

Редагувати: Ось посилання на Spring AOP, щоб розпочати роботу, якщо ви зацікавлені. Це найдоступніша реалізація AOP, яку я стикаюся для Java.

Також, враховуючи дуже прості пропозиції всіх інших, я повинен додати, що AOP - це коли ви не хочете, щоб такі речі, як терміни, вторглися у ваш код. Але у багатьох випадках такий простий і легкий підхід чудово.


3
Ось підручник про те, як це зробити з Весною: veerasundar.com/blog/2010/01/…
Девід Тінкер

39

System.currentTimeMillis();НЕ є хорошим підходом до вимірювання продуктивності ваших алгоритмів. Він вимірює загальний час, який ви переживаєте, як користувач переглядає екран комп'ютера. Він також включає час, витрачений на все, що працює на вашому комп’ютері у фоновому режимі. Це може призвести до величезних змін, якщо у вас на робочій станції працює багато програм.

Правильний підхід - це використання java.lang.managementпакету.

З веб-сайту http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking :

  • "Користувацький час" - це час, витрачений на виконання власного коду вашої програми.
  • "Системний час" - це час, витрачений на виконання коду ОС від імені вашої програми (наприклад, для вводу / виводу).

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

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}

4
Це, безумовно, хороший момент, що "час користувача" (час настінного годинника) не завжди є великим показником продуктивності, особливо в багатопотоковій програмі.
Псалом Огр33,

Це відповідь, яку я шукаю.
ЧжаоГан

30

З Java 8 ви також можете зробити щось подібне з усіма нормальними методами :

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

з TimeIt як:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

За допомогою цього методу ви можете легко виміряти час у будь-якому місці коду, не порушуючи його. У цьому простому прикладі я просто друкую час. Можна додати комутатор для TimeIt, наприклад, лише для друку часу в DebugMode або чогось іншого.

Якщо ви працюєте з Function, ви можете робити щось подібне:

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}

Це виглядає набагато краще, ніж інші рішення. Його ближче до Spring AOP, але легше, ніж це. Справжня Java 8 спосіб! +1 Дякую!
Аміт Кумар

Можливо, це вам добре здається, адже Стефан використовує нові фантастичні функції java. Але я думаю, що це важко читати і розуміти.
Кіт Стімпсона

18

Також для вимірювання часу ми можемо використовувати клас StopWatch спільноти Apache.

Зразок коду

org.apache.commons.lang.time.StopWatch sw = new org.apache.commons.lang.time.StopWatch();

System.out.println("getEventFilterTreeData :: Start Time : " + sw.getTime());
sw.start();

// Method execution code

sw.stop();
System.out.println("getEventFilterTreeData :: End Time : " + sw.getTime());

15

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

    int runs = 0, runsPerRound = 10;
    long begin = System.nanoTime(), end;
    do {
        for (int i=0; i<runsPerRound; ++i) timedMethod();
        end = System.nanoTime();
        runs += runsPerRound;
        runsPerRound *= 2;
    } while (runs < Integer.MAX_VALUE / 2 && 1000000000L > end - begin);
    System.out.println("Time for timedMethod() is " + 
        0.000000001 * (end-begin) / runs + " seconds");

Звичайно, застереження про використання настінного годинника застосовуються: вплив JIT-компіляція, кілька потоків / процеси і т.д. Таким чином, ви повинні спочатку виконати методу багато разів першим, так що JIT компілятор виконує свою роботу, а потім повторіть цей тест кілька разів і візьміть найменший час виконання.


13

Для цього ми використовуємо анотації AspectJ та Java. Якщо нам потрібно знати час виконання методу, ми просто пояснюємо його. Більш просунута версія може використовувати власний рівень журналу, який можна вмикати та вимикати під час виконання.

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}

13

JEP 230: Microbenchmark Suite

FYI, JEP 230: Microbenchmark Suite - це проект OpenJDK для:

Додайте базовий набір мікро-позначок до вихідного коду JDK та полегшити розробникам запуск існуючих мікро-позначок та створення нових.

Ця функція надійшла на Java 12 .

Проводка Java Microbenchmark (JMH)

Для більш ранніх версій Java ознайомтеся з проектом джгута Java Microbenchmark (JMH), на якому базується JEP 230.


11

Дійсно хороший код.

http://www.rgagnon.com/javadetails/java-0585.html

import java.util.concurrent.TimeUnit;

long startTime = System.currentTimeMillis();
........
........
........
long finishTime = System.currentTimeMillis();

String diff = millisToShortDHMS(finishTime - startTime);


  /**
   * converts time (in milliseconds) to human-readable format
   *  "<dd:>hh:mm:ss"
   */
  public static String millisToShortDHMS(long duration) {
    String res = "";
    long days  = TimeUnit.MILLISECONDS.toDays(duration);
    long hours = TimeUnit.MILLISECONDS.toHours(duration)
                   - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
                     - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
                   - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    if (days == 0) {
      res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    else {
      res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
    }
    return res;
  }

3
Власне питання полягав у тому, як обчислити кількість часу, який займає метод, а не як його форматувати. Однак це питання досить старе (майже чотири роки!). Постарайтеся уникати відродження старих ниток, якщо відповідь не додасть щось нове та значне порівняно з існуючими відповідями.
Лі

1
І щоб додати решту мілі до кінця, внесіть такі зміни: 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); }
Рік Баркхаус

10

Ви можете використовувати Perf4j . Дуже класна утиліта. Використання просте

String watchTag = "target.SomeMethod";
StopWatch stopWatch = new LoggingStopWatch(watchTag);
Result result = null; // Result is a type of a return value of a method
try {
    result = target.SomeMethod();
    stopWatch.stop(watchTag + ".success");
} catch (Exception e) {
    stopWatch.stop(watchTag + ".fail", "Exception was " + e);
    throw e; 
}

Більше інформації можна знайти в Посібнику розробника

Редагувати: проект здається мертвим


1
Perf4j також може генерувати хороші статистичні дані .
Пааске

8
new Timer(""){{
    // code to time 
}}.timeMe();



public class Timer {

    private final String timerName;
    private long started;

    public Timer(String timerName) {
        this.timerName = timerName;
        this.started = System.currentTimeMillis();
    }

    public void timeMe() {
        System.out.println(
        String.format("Execution of '%s' takes %dms.", 
                timerName, 
                started-System.currentTimeMillis()));
    }

}

1
Згорніть свій власний простий клас - хороший вибір, коли у вас вже створена система складання та залежна OTS, і ви не хочете турбуватися про втягнення в інший пакет OTS, що включає клас таймера утиліти.
Псалом Огре3333

7

Я в основному змінюю це, але враховуючи, як працює компіляція точки доступу, якщо ви хочете отримати точні результати, вам потрібно викинути перші вимірювання та переконатися, що ви використовуєте метод у реальному світі (читайте конкретний додаток).

Якщо JIT вирішить скласти його, ваші номери сильно різняться. тому просто будьте в курсі


7

Використовуючи AOP / AspectJ та @Loggableпримітки з jcabi-аспектів, ви можете зробити це легко і компактно:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

Кожен виклик цього методу буде надісланий до лісозаготівельного пункту SLF4J з DEBUGрівнем реєстрації. І кожне повідомлення журналу буде включати час виконання.


7

Spring надає клас утиліти org.springframework.util.StopWatch , відповідно до JavaDoc:

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

Використання:

StopWatch stopWatch = new StopWatch("Performance Test Result");

stopWatch.start("Method 1");
doSomething1();//method to test
stopWatch.stop();

stopWatch.start("Method 2");
doSomething2();//method to test
stopWatch.stop();

System.out.println(stopWatch.prettyPrint());

Вихід:

StopWatch 'Performance Test Result': running time (millis) = 12829
-----------------------------------------
ms     %     Task name
-----------------------------------------
11907  036%  Method 1
00922  064%  Method 2

З аспектами:

@Around("execution(* my.package..*.*(..))")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Object retVal = joinPoint.proceed();
    stopWatch.stop();
    log.info(" execution time: " + stopWatch.getTotalTimeMillis() + " ms");
    return retVal;
}

Чи можливо це використовувати за допомогою AspectJ?
зигімантус

7

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

Execution Time: 9 Minutes, 36 Seconds, 237 MicroSeconds, 806193 NanoSeconds

Код тут:

public class series
{
    public static void main(String[] args)
    {
        long startTime = System.nanoTime();

        long n = 10_00_000;
        printFactorial(n);

        long endTime = System.nanoTime();
        printExecutionTime(startTime, endTime);

    }

    public static void printExecutionTime(long startTime, long endTime)
    {
        long time_ns = endTime - startTime;
        long time_ms = TimeUnit.NANOSECONDS.toMillis(time_ns);
        long time_sec = TimeUnit.NANOSECONDS.toSeconds(time_ns);
        long time_min = TimeUnit.NANOSECONDS.toMinutes(time_ns);
        long time_hour = TimeUnit.NANOSECONDS.toHours(time_ns);

        System.out.print("\nExecution Time: ");
        if(time_hour > 0)
            System.out.print(time_hour + " Hours, ");
        if(time_min > 0)
            System.out.print(time_min % 60 + " Minutes, ");
        if(time_sec > 0)
            System.out.print(time_sec % 60 + " Seconds, ");
        if(time_ms > 0)
            System.out.print(time_ms % 1E+3 + " MicroSeconds, ");
        if(time_ns > 0)
            System.out.print(time_ns % 1E+6 + " NanoSeconds");
    }
}

6

Є кілька способів зробити це. Я зазвичай відновлююся просто використовуючи щось подібне:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

або те ж саме з System.nanoTime ();

Щось більше, що стосується референтних речей, схоже, є і таке: http://jetm.void.fm/ Ніколи цього не пробував.


6

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

<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>

І налаштуйте його для свого оточення.

Методи можна помітити за допомогою @Timed :

@Timed
public void exampleMethod(){
    // some code
}

або шматок коду, обгорнутий таймером :

final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();

Агреговані показники можна експортувати в консолі, JMX, CSV або інші.

@Timed Приклад виведення показників:

com.example.ExampleService.exampleMethod
             count = 2
         mean rate = 3.11 calls/minute
     1-minute rate = 0.96 calls/minute
     5-minute rate = 0.20 calls/minute
    15-minute rate = 0.07 calls/minute
               min = 17.01 milliseconds
               max = 1006.68 milliseconds
              mean = 511.84 milliseconds
            stddev = 699.80 milliseconds
            median = 511.84 milliseconds
              75% <= 1006.68 milliseconds
              95% <= 1006.68 milliseconds
              98% <= 1006.68 milliseconds
              99% <= 1006.68 milliseconds
            99.9% <= 1006.68 milliseconds

5

Якщо ви хочете часу настінного годинника

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;

5

Як сказав "skaffman", використовуйте AOP АБО ви можете використовувати плетіння байт-коду часу виконання, як і інструменти покриття тестових методів одиниці, щоб прозоро додавати інформацію про час до викликаних методів.

Ви можете переглянути код, який використовується у інструментах з відкритим кодом, таких як Emma ( http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0 ). Інший інструмент покриття відкритих джерел - http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download .

Якщо вам в кінцевому підсумку вдасться зробити те, що ви задали, pls. поділіться ним із спільнотою тут зі своїми мурашиними завданнями / банками.


4
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds

4

Я змінив код з правильної відповіді, щоб отримати результат за секунди:

long startTime = System.nanoTime();

methodCode ...

long endTime = System.nanoTime();
double duration = (double)(endTime - startTime) / (Math.pow(10, 9));
Log.v(TAG, "MethodName time (s) = " + duration);

4

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

Код:

StopWatch stopWatch = new StopWatch()
stopWatch.start();  //start stopwatch
// write your function or line of code.
stopWatch.stop();  //stop stopwatch
stopWatch.getTotalTimeMillis() ; ///get total time

Документація для секундоміра: Простий секундомір, що дозволяє визначати час виконання декількох завдань, виставляючи загальний час роботи та час виконання для кожного заданого завдання. Приховує використання System.currentTimeMillis (), покращуючи читабельність коду програми та зменшуючи ймовірність помилок обчислення. Зауважте, що цей об'єкт не розроблений як безпечний для потоків і не використовує синхронізацію. Цей клас зазвичай використовується для перевірки продуктивності під час перевірки концепцій та в процесі розробки, а не як частина виробничих додатків.


3

Ви можете спробувати таким чином, якщо просто хочете знати час.

long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));    

3

Гаразд, це простий клас, який буде використовуватися для простого простого виконання функцій. Нижче є приклад.

public class Stopwatch {
    static long startTime;
    static long splitTime;
    static long endTime;

    public Stopwatch() {
        start();
    }

    public void start() {
        startTime = System.currentTimeMillis();
        splitTime = System.currentTimeMillis();
        endTime = System.currentTimeMillis();
    }

    public void split() {
        split("");
    }

    public void split(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Split time for [" + tag + "]: " + (endTime - splitTime) + " ms");
        splitTime = endTime;
    }

    public void end() {
        end("");
    }
    public void end(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Final time for [" + tag + "]: " + (endTime - startTime) + " ms");
    }
}

Зразок використання:

public static Schedule getSchedule(Activity activity_context) {
        String scheduleJson = null;
        Schedule schedule = null;
/*->*/  Stopwatch stopwatch = new Stopwatch();

        InputStream scheduleJsonInputStream = activity_context.getResources().openRawResource(R.raw.skating_times);
/*->*/  stopwatch.split("open raw resource");

        scheduleJson = FileToString.convertStreamToString(scheduleJsonInputStream);
/*->*/  stopwatch.split("file to string");

        schedule = new Gson().fromJson(scheduleJson, Schedule.class);
/*->*/  stopwatch.split("parse Json");
/*->*/  stopwatch.end("Method getSchedule"); 
    return schedule;
}

Зразок виходу консолі:

Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms

3

У Java 8 Instantвведено новий клас з назвою . Відповідно до документа:

Миттєвий позначає початок наносекунди на часовій лінії. Цей клас корисний для створення часової позначки для відображення машинного часу. Діапазон миттєвого вимагає збереження числа, більшого, ніж довге. Щоб досягти цього, клас зберігає довгі епохи-секунди та int, що представляє наносекунд секунди, який завжди буде від 0 до 999,999,999. Епохи секунд вимірюються від стандартної епохи Java 1970-01-01T00: 00: 00Z, де моменти після епохи мають позитивні значення, а більш ранні моменти мають негативні значення. І для епох-другої, і для наносекундної частини більша величина завжди пізніше на часовій лінії, ніж менша.

Це може використовуватися як:

Instant start = Instant.now();
try {
    Thread.sleep(7000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

Це друкує PT7.001S.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.