Charlie-Blake
Charlie-Blake

Reputation: 11050

Measuring method time

I want to optimize a method so it runs in less time. I was using System.currentTimeMillis() to calculate the time it lasted.

However, I just read the System.currentTimeMillis() Javadoc and it says this:

This method shouldn't be used for measuring timeouts or other elapsed time measurements, as changing the system time can affect the results.

So, if I shouldn't use it to measure the elapsed time, how should I measure it?

Upvotes: 0

Views: 206

Answers (5)

polomo12
polomo12

Reputation: 95

Welcome to the world of benchmarking.

As others point out - techniques based on timing methods like currentTimeMillis will only tell you elapsed time, rather than how long the method spent in the CPU.

I'm not aware of a way in Java to isolate timings of a method to how long it spent on the CPU - the answer is to either: 1) If the method is long running (or you run it many times, while using benchmarking rules like do not discard every result), use something like the "time" tool on Linux (http://linux.die.net/man/1/time) who will tell you how long the app spent on the CPU (obviously you have to take away the overhead of the application startup etc). 2) Use a profiler as others pointed out. This has dangers such as adding too much overhead using tracing techniques - if it uses stack sampling, it won't be 100% accurate 3) Am not sure how feasible this is on android - but you could get your bechmark running on a quiet multicore system and isolate a core (or ideally whole socket) to only be able to run your application.

Upvotes: 1

Neron T
Neron T

Reputation: 369

Android native Traceview will help you measuring the time and also will give you more information. Using it is as simple as:

// start tracing to "/sdcard/calc.trace"
Debug.startMethodTracing("calc");
// ...
// stop tracing
Debug.stopMethodTracing();

A post with more information in Android Developers Blog

Also take @Rajesh J Advani post into account.

Upvotes: 2

Rajesh J Advani
Rajesh J Advani

Reputation: 5710

There are a few issues with System.currentTimeMillis().

  1. if you are not in control of the system clock, you may be reading the elapsed time wrong.
  2. For server code or other long running java programs, your code is likely going to be called in over a few thousand iterations. By the end of this time, the JVM will have optimized the bytecode to the extent where the time taken is actually a lot lesser than what you measured as part of your testing.
  3. It doesn't take into account the fact that there might be other processes on your computer or other threads in the JVM that compete for CPU time.

You can still use the method, but you need to keep the above points in mind. As others have mentioned, a profiler is a much better way of measuring system performance.

Upvotes: 1

topduo
topduo

Reputation: 508

SystemClock.elapsedRealtime()

Quoting words in the linked page: elapsedRealtime() and elapsedRealtimeNanos() return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.

Upvotes: -1

ujwalendu
ujwalendu

Reputation: 79

You can use something called System.nanoTime(). As given here http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime()

As the document says

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.

Hope this will help.

Upvotes: -1

Related Questions