Comment puis-je obtenir le temps d'exécution d'une méthode? Existe-t-il une classe d’utilitaire Timer pour des tâches telles que le chronométrage d’une tâche, etc.?
La plupart des recherches sur Google donnent des résultats pour des minuteries qui planifient des threads et des tâches, ce qui n'est pas ce que je veux.
Il y a toujours la manière démodée:
long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();
long duration = (endTime - startTime); //divide by 1000000 to get milliseconds.
Je vais avec la réponse simple. Travaille pour moi.
long startTime = System.currentTimeMillis();
doReallyLongThing();
long endTime = System.currentTimeMillis();
System.out.println("That took " + (endTime - startTime) + " milliseconds");
Ça marche plutôt bien. La résolution est évidemment seulement à la milliseconde, vous pouvez faire mieux avec System.nanoTime (). Il existe certaines limites aux deux (tranches de calendrier du système d'exploitation, etc.), mais cela fonctionne plutôt bien.
Moyenne sur quelques courses (plus il y a de mieux) et vous aurez une bonne idée.
Allez les gars! Personne n'a mentionné le moyen Guava de le faire (ce qui est sans doute génial):
import com.google.common.base.Stopwatch;
Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());
La bonne chose est que Stopwatch.toString () fait un bon travail de sélection des unités de temps pour la mesure. C'est à dire. si la valeur est petite, la sortie sera de 38 ns, si elle est longue, elle affichera 5 m 3
Encore plus sympa:
Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
timer.start();
methodToTrackTimeFor();
timer.stop();
methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);
Remarque: Google Guava nécessite Java 1.6 + .
Utilisez un profileur (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, etc.). Vous obtiendrez les résultats les plus précis et le moins intrusif. Ils utilisent le mécanisme de profilage intégré de la machine virtuelle Java qui peut également vous fournir des informations supplémentaires telles que des traces de pile, des chemins d'exécution et des résultats plus complets, si nécessaire.
Lorsque vous utilisez un profileur entièrement intégré, il est facile de profiler une méthode. Cliquez avec le bouton droit sur Profiler -> Ajouter aux méthodes racine. Ensuite, exécutez le profileur comme si vous faisiez un test ou un débogueur.
Réunis tous les moyens possibles en un seul endroit.
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);
Système . 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 ) );
Lecture humaine Format
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;
}
Goyave: Google Chronomètre JAR "Un des buts de Stopwatch est de mesurer le temps écoulé en nanosecondes.
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 LangJAR " Chronomètre fournit une API pratique pour les timings.
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 de date/heure Java de Java 8 "Un objet Durée représente une période de temps entre deux - Instantané objets.
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 fournit la classe d'utilitaire Chronomètre pour mesurer le temps écoulé en 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());
}
Sortie:
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]
Ce n'est probablement pas ce que vous vouliez que je dise, mais c'est un bon usage de l'AOP. Fouettez un intercepteur proxy autour de votre méthode et faites le chronométrage.
Le quoi, pourquoi et comment d'AOP dépasse malheureusement le cadre de cette réponse, mais c'est ce que je ferais probablement.
Edit: Voici un lien vers Spring AOP pour vous aider à démarrer, si vous êtes désireux. Il s’agit de l’implémentation la plus accessible d’AOP que j’ai rencontrée pour Java.
De plus, étant donné les suggestions très simples de tous les autres, je devrais ajouter que l'AOP est pour quand vous ne voulez pas que des choses comme le minutage envahissent votre code. Mais dans de nombreux cas, ce type d’approche simple et facile est acceptable.
System.currentTimeMillis();
IS PAS une bonne approche pour mesurer la performance de vos algorithmes. Il mesure le temps total passé en tant qu'utilisateur à regarder l'écran de l'ordinateur. Cela inclut également le temps consommé par tout le reste exécuté en arrière-plan sur votre ordinateur. Cela pourrait faire une énorme différence dans le cas où de nombreux programmes sont exécutés sur votre poste de travail.
L’approche appropriée utilise le package Java.lang.management
.
De http://nadeausoftware.com/articles/2008/03/Java_tip_how_get_cpu_and_user_time_benchmarking site Web:
La méthode getCpuTime()
vous donne la somme de ceux-ci:
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;
}
}
Avec Java 8, vous pouvez faire quelque chose comme ceci avec toutes les méthodes normales méthodes:
Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue
avec TimeIt comme:
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;
}
}
Avec cette méthode, vous pouvez facilement mesurer le temps n'importe où dans votre code sans le casser. Dans cet exemple simple, je viens d'imprimer le temps. Pouvez-vous ajouter un commutateur pour TimeIt, par exemple pour imprimer uniquement l'heure dans DebugMode ou quelque chose comme ça.
Si vous travaillez avec Fonction vous pouvez faire quelque chose comme ceci:
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;
};
}
Nous pouvons également utiliser la classe StopWatch de Apache commons pour mesurer le temps.
Exemple de code
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());
Juste une petite astuce, si vous n'utilisez pas d'outillage et que vous voulez utiliser des méthodes avec un temps d'exécution peu élevé: exécutez-le plusieurs fois, en doublant chaque fois le nombre d'exécutions jusqu'à atteindre une seconde, voire plus. Ainsi, l'heure de l'appel à System.nanoTime et ainsi de suite, ni l'exactitude de System.nanoTime n'influent beaucoup sur le résultat.
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");
Bien sûr, les mises en garde relatives à l’utilisation de l’horloge murale s’appliquent: influences de la compilation JIT, de multiples threads/processus, etc. Ainsi, vous devez d’abord exécuter la méthode beaucoup plusieurs fois en premier, de sorte que le JIT Le compilateur fait son travail, puis répète ce test plusieurs fois et prend le temps d'exécution le plus bas.
Nous utilisons les annotations AspectJ et Java à cette fin. Si nous avons besoin de connaître le temps d'exécution d'une méthode, nous l'annotons simplement. Une version plus avancée pourrait utiliser un niveau de journal propre qui peut être activé et désactivé au moment de l'exécution.
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;
}
[...]
}
Vraiment bon code.
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;
}
Pour votre information, JEP 230: Microbenchmark Suite est un OpenJDK projet destiné à:
Ajoutez une suite basique de micro-critères au code source du JDK et aidez les développeurs à exécuter des micro-critères existants et à en créer de nouveaux.
Cette fonctionnalité est arrivée dans Java 12 .
Pour les versions antérieures de Java, consultez le projet Java Microbenchmark Harness (JMH) sur lequel est basé JEP 230.
Vous pouvez utiliser Perf4j . Utilité très cool. L'utilisation est simple
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;
}
Plus d'informations peuvent être trouvées dans Guide du développeur
Edit: Le projet semble mort
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()));
}
}
En utilisant AOP/AspectJ et @Loggable
l'annotation de jcabi-aspects vous pouvez le faire facilement et de manière compacte:
_@Loggable(Loggable.DEBUG)
public String getSomeResult() {
// return some value
}
_
Chaque appel à cette méthode sera envoyé à la fonction d’enregistrement SLF4J avec le niveau d’enregistrement DEBUG
. Et chaque message du journal inclura le temps d'exécution.
Je fais essentiellement des variantes de ceci, mais vu le fonctionnement de la compilation de hotspot, si vous voulez obtenir des résultats précis, vous devez jeter les premières mesures et vous assurer que vous utilisez la méthode dans une application du monde réel (à lire, spécifique à l'application).
Si le JIT décide de le compiler, vos chiffres varieront beaucoup. alors juste être conscient
Spring fournit une classe d’utilitaire org.springframework.util.StopWatch , conformément à JavaDoc:
Chronomètre simple, permettant de chronométrer un certain nombre de tâches, exposant la durée totale et la durée totale de chaque tâche nommée.
Usage:
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());
Sortie:
StopWatch 'Performance Test Result': running time (millis) = 12829
-----------------------------------------
ms % Task name
-----------------------------------------
11907 036% Method 1
00922 064% Method 2
Avec les aspects:
@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;
}
J'ai écrit une méthode pour imprimer le temps d'exécution de la méthode sous une forme très lisible. Par exemple, pour calculer la factorielle de 1 million, cela prend environ 9 minutes. Donc, le temps d'exécution est imprimé comme:
Execution Time: 9 Minutes, 36 Seconds, 237 MicroSeconds, 806193 NanoSeconds
Le code est ici:
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");
}
}
Il y a deux façons de le faire. Je retombe normalement à utiliser quelque chose comme ceci:
long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();
ou la même chose avec System.nanoTime ();
Pour plus de comparaisons, il semble également y avoir celui-ci: http://jetm.void.fm/ Je l’ai jamais essayé.
Si vous voulez l'heure de l'horloge
long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;
Comme "skaffman" a dit, utilisez AOP OR, vous pouvez utiliser le tissage de code unique d'exécution, tout comme les outils de couverture de méthode de test unitaire utilisés pour ajouter de manière transparente des informations de synchronisation aux méthodes invoquées.
Vous pouvez consulter le code utilisé par des outils open source comme Emma ( http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror= ). L’autre outil de couverture opensource est http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download .
Si vous réussissez finalement à faire ce que vous vous êtes fixé, pls. partagez-le avec la communauté ici avec votre tâche/vos pots de fourmi.
Vous pouvez utiliser la bibliothèque Metrics qui fournit divers instruments de mesure. Ajouter une dépendance:
<dependencies>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics.version}</version>
</dependency>
</dependencies>
Et configurez-le pour votre environnement.
Les méthodes peuvent être annotées avec @ Timed :
@Timed
public void exampleMethod(){
// some code
}
ou un morceau de code enveloppé avec Timer :
final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();
Les métriques agrégées peuvent être exportées vers la console, JMX, CSV ou autre.
@Timed
exemple de sortie de métrique:
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
Vous pouvez utiliser la classe chronomètre du projet de base de printemps:
Code:
StopWatch stopWatch = new StopWatch()
stopWatch.start(); //start stopwatch
// write your function or line of code.
stopWatch.stop(); //stop stopwatch
stopWatch.getTotalTimeMillis() ; ///get total time
Documentation pour Chronomètre: Chronomètre simple, permettant de chronométrer un certain nombre de tâches, en exposant la durée d'exécution totale et la durée d'exécution de chaque tâche nommée. Dissimule l'utilisation de System.currentTimeMillis (), améliorant la lisibilité du code d'application et réduisant la probabilité d'erreurs de calcul. Notez que cet objet n'est pas conçu pour être thread-safe et n'utilise pas de synchronisation. Cette classe est normalement utilisée pour vérifier les performances lors de la validation des concepts et du développement, plutôt que dans le cadre d'applications de production.
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds
J'ai modifié le code de la réponse correcte pour obtenir le résultat en quelques secondes:
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);
Ok, ceci est une classe simple à utiliser pour un simple chronométrage simple de vos fonctions. Il y a un exemple ci-dessous.
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");
}
}
Échantillon d'utilisation:
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;
}
Exemple de sortie de la console:
Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms
Dans Java 8, une nouvelle classe nommée Instant
est introduite. Selon doc:
Instant représente le début d'une nanoseconde sur la ligne de temps. Cette classe est utile pour générer un horodatage représentant l'heure de la machine. La plage d'un instant nécessite le stockage d'un nombre plus grand qu'un long. Pour y parvenir, la classe stocke une valeur longue représentant Epoch-seconds et un int représentant une nanoseconde-seconde, qui sera toujours comprise entre 0 et 999 999 999. Les secondes d’époque sont mesurées à partir de la norme Java d’époque du 1970-01-01T00: 00: 00Z où les instants après l’époque ont des valeurs positives et les instants antérieurs des valeurs négatives. Pour les parties Epoch-seconde et Nanoseconde, une valeur plus grande est toujours plus tardive sur la ligne de temps qu'une valeur plus petite.
Ceci peut être utilisé comme:
Instant start = Instant.now();
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));
Il imprime PT7.001S
.
Vous pouvez essayer de cette façon si vous voulez simplement connaître l'heure.
long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));
System.nanoTime()
est un utilitaire système assez précis pour mesurer le temps d'exécution. Mais faites attention, si vous utilisez le mode de planification préemptif (par défaut), cet utilitaire mesure en réalité le temps de l'horloge murale et non le temps de calcul. Par conséquent, vous remarquerez peut-être différentes valeurs de temps d'exécution d'une exécution à l'autre, en fonction des charges système. Si vous recherchez du temps CPU, je pense que faire fonctionner votre programme en mode temps réel fera l'affaire. Vous devez utiliser RT linux. lien: Programmation en temps réel avec Linux
Ce serait bien si Java avait un meilleur support fonctionnel, de sorte que l'action, qui doit être mesurée, puisse être encapsulée dans un bloc:
measure {
// your operation here
}
En Java cela pourrait être fait par des fonctions anonymes, qui ont l'air trop prolixes
public interface Timer {
void wrap();
}
public class Logger {
public static void logTime(Timer timer) {
long start = System.currentTimeMillis();
timer.wrap();
System.out.println("" + (System.currentTimeMillis() - start) + "ms");
}
public static void main(String a[]) {
Logger.logTime(new Timer() {
public void wrap() {
// Your method here
timeConsumingOperation();
}
});
}
public static void timeConsumingOperation() {
for (int i = 0; i<=10000; i++) {
System.out.println("i=" +i);
}
}
}
Voici de jolies chaînes imprimées prêtes à l'emploi, formatées, similaires au temps de recherche google nécessaire à la recherche:
long startTime = System.nanoTime();
// ... methodToTime();
long endTime = System.nanoTime();
long duration = (endTime - startTime);
long seconds = (duration / 1000) % 60;
// formatedSeconds = (0.xy seconds)
String formatedSeconds = String.format("(0.%d seconds)", seconds);
System.out.println("formatedSeconds = "+ formatedSeconds);
// i.e actual formatedSeconds = (0.52 seconds)
Mesures de performance sur ma machine
Comme mentionné, System.nanoTime () est censé mesurer le temps écoulé. Soyez juste conscient du coût si vous utilisez une boucle ou similaire.
J'ai implémenté une simple minuterie, et je pense que c'est vraiment utile:
public class Timer{
private static long start_time;
public static double tic(){
return start_time = System.nanoTime();
}
public static double toc(){
return (System.nanoTime()-start_time)/1000000000.0;
}
}
De cette façon, vous pouvez chronométrer une ou plusieurs actions:
Timer.tic();
// Code 1
System.out.println("Code 1 runtime: "+Timer.toc()+" seconds.");
// Code 2
System.out.println("(Code 1 + Code 2) runtime: "+Timer.toc()+"seconds");
Timer.tic();
// Code 3
System.out.println("Code 3 runtime: "+Timer.toc()+" seconds.");
Vous pouvez utiliser javaagent pour modifier les octets de la classe Java, ajoutez les codes du moniteur de manière dynamique. Certains outils Open Source sur le github peuvent le faire pour vous.
Si vous voulez le faire vous-même, implémentez simplement le javaagent, utilisez javassist pour modifier les méthodes que vous voulez surveiller et le code du moniteur avant votre method return.it est propre et vous pouvez surveiller les systèmes pour lesquels vous n'avez même pas de code source.
Une stratégie qui me convient dans Java ee était la suivante:
Créez une classe avec une méthode annotée avec @AroundInvoke
;
@Singleton
public class TimedInterceptor implements Serializable {
@AroundInvoke
public Object logMethod(InvocationContext ic) throws Exception {
Date start = new Date();
Object result = ic.proceed();
Date end = new Date();
System.out.println("time: " + (end.getTime - start.getTime()));
return result;
}
}
Annotez la méthode que vous souhaitez surveiller:
@Interceptors(TimedInterceptor.class)
public void onMessage(final Message message) { ...
J'espère que cela peut aider.