Macie jakiś wzorzec do łapania milisekund wykonania czynności ?

0

Taki wzorzec do łapania czasu czasu, wykonania, w sposób oczywisty ohydny

long t0 = System.nanoTime();
Type t = doSomething()
long t9 = System.nanoTime();

(t9-t0)/1000 -> tu mam mikrosekundy ...

Prawdę mówiąc w różnych projektach "coś" próbowaliśmy, ale nic z tego co pamiętam nie wzbudziło takiego entuzjazmu, aby powtarzać w następnym.
Oczywiście mocne wdrożenie aspektowe by dało wyniki, ale to strzelanie z armaty do wróbla.
Przyjmijmy, że nie chodzi o żadne kontenery, myślimy Javą SE.

Któraś koncepcja ...

class MyMonitor<T> {
   final long t0 = System.nanoTime();
   long t9;
   public T fire( T val ) {
       T x = val;
       t9 = System.nanoTime();
   }
   public long ms(){
      return (t9-t0) / 1000000;
   }
}

MyMonitor<cośik> mm = new MyMonitor();
var cosik = mm.fire( doSomething() );
mm.ms() ; // mamy

Ciągle mam przeczucie, że istnieje sprytne rozwiązanie.
W C bym to napisał, z ohydnymi makrami, a w Javie nie wychodzi nic ładnego

3

Najważniejsze pytanie na co Ci to, bo jeśli chcesz w ten sposób oceniać "wydajność" to ta metoda średnio działa (w zasadzie nie działa).

A jak po prostu jako monitoring / alert to wtedy opiernicz to lambdą.

monitor.execute( ()-> {... kod ...});

0

A jest w Javie jakiś fajny pattern wydobycie na runtime np liniii kodu?
Bo np w C# jest (o C/C++ nie mówię, każdy wie).

1
ZrobieDobrze napisał(a):

A jest w Javie jakiś fajny pattern wydobycie na runtime np liniii kodu?
Bo np w C# jest (o C/C++ nie mówię, każdy wie).

Thread.currentThread().getStackTrace() i potem jedziesz.

1

Jeśli chcecie coś bardziej "enterprajs" w zasadzie defaultowym wyborem jest ta libka - https://micrometer.io/docs/concepts#_timer

Tak na szybko coś takiego można sobie naskrobać, tutaj dużo zależy czego tak naprawdę chcecie i czy np. interesują was przypadki z exceptionami i czy nie chcecie jakichś gotowych funkcyjnych "Result" użyć :)


import java.time.Duration;
import java.time.Instant;
import java.util.Random;
import java.util.concurrent.Callable;

public final class Measured {

    public static <T> Result<T> run(Callable<T> callable) {
        Instant before = Instant.now();
        try {
            return Result.success(callable.call(), Duration.between(before, Instant.now()));
        } catch (Exception exception) {
            return Result.failure(exception, Duration.between(before, Instant.now()));
        }
    }

    public static class Result<T> {

        private final T value;
        private final Throwable throwable;
        private final Duration executionTime;

        private Result(T value, Throwable throwable, Duration executionTime) {
            this.value = value;
            this.throwable = throwable;
            this.executionTime = executionTime;
        }

        public T value() {
            return value;
        }

        public Throwable throwable() {
            return throwable;
        }

        public Duration executionTime() {
            return executionTime;
        }

        static <T> Result<T> success(T value, Duration executionTime) {
            return new Result<>(value, null, executionTime);
        }

        static <T> Result<T> failure(Throwable throwable, Duration executionTime) {
            return new Result<T>(null, throwable, executionTime);
        }
    }

    public static void main(String[] args) {
        
        Result<String> result = Measured.run(() -> {
            Thread.sleep(new Random().nextInt(100));
            return "ok!";
        });
        System.out.println(result.value());
        System.out.println(result.executionTime());

        Result<?> badResult = Measured.run(() -> {
            Thread.sleep(new Random().nextInt(100));
            throw new RuntimeException("not ok!");
        });
        System.out.println(badResult.executionTime());
        badResult.throwable().printStackTrace();
    }
}
2

Ten micrometer to bardziej sensowne rozwiązanie, zwłaszcza, że ma statystyki. Ale mimo to do mierzenia co spowalnia produkcję się nie nadaje.
Przykład - Thread.sleep(1000) pokaże 100 razy tyle czasu co Thread.sleep(10), a spowalniają produkcję tak samo.
Oczywiście zamiast Thread.sleep możesz mieć wywołanie jakiegoś serwisu http który akurat mocno laguje. Twojej produkcji to nie obciąża, a czasy będą słabe.

To czego szukasz to profilowanie - sprawdź https://visualvm.github.io

1 użytkowników online, w tym zalogowanych: 0, gości: 1