Code optimization; measure time between code sections - java

I would like to see how long it takes for a certain method to execute in my android app. My first idea was to do something like this:
Date date1 = new Date();
doStuff();
Date date2 = new Date();
//compare date difference in ms
But for starters, date objects doesnt seem to have a .getMilliseconds(), and thats what im after. Is there any easier and / or better way to solve this?
Thanks

You'll probably want to use System.nanoTime() to do your time counting, as it uses the highest-precision timer available. Another thing to do when testing code efficiency is to not just run it once, but to run it repeatedly, and take the average time as your estimate. This gives better results in the long run, as CPU usage can spike if some other program is also trying to run.

What is wrong with System.currentTimeMillis()?
long before = System.currentTimeMillis();
doStuff();
long after = System.currentTimeMillis();

You could use the Android profiling tools, which can do this kind of stuff in a nice graphical view as the app is running in the emulator.
More info here: http://developer.android.com/tools/debugging/debugging-tracing.html

Related

How to measure exact execution time for a process/method that gets frequently interrupted?

Currently this is how I get time elapsed for a process to get completed.
long start = System.currentTimeMillis();
process();
long end = System.currentTimeMillis();
long duration = stop - start;
System.out.println(duration);
The problem I am facing currently is the process() gets interrupted(paused) by my pc's hibernation whenever there's no power(My work environment is outside so I have to be on battery) so that it can continue whenever I restart the pc when plugged. I am fully aware I would get a wrong duration if for example I am not able to restart for about 2hrs since the process got paused(during hibernation) as this would mean the extra 2hrs will be accounted for by the CPU clock via the CMOS battery backup whenever the line
long end = System.currentTimeMillis();
is reached. How would it be possible to get the exact duration irrespective of the process being paused severally.
So your question is "how much wall clock time was taken by the process, without time spent in hibernation". Well, wall clock time is easy to get, but you don't really have a chance to know whether hibernation happened or not.
However...
If your process is a set of discrete steps, you could do something like the following
List<Duration> durations = new ArrayList<>();
for(Step step : steps) {
Instant stepStart = Instant.now();
process(step);
durations.add(Duration.between(stepStart, Instant.now()));
}
long totalMillis = durations.stream()
.mapToLong(Duration::toMillis)
.filter(ms -> ms < 1000) // Cut off limit, to disregard hibernate steps
.sum();
This times each step separately, and if the time for a step takes more than 1 second, it's not taken into account in the total. You could also use an "average" time for those steps, so the end result would be a bit more realistic (of course this depends on the number of steps, the assumed runtime of a single step, etc.).
This only works if there is a good limit to what is "too much" time, and it provides a less accurate result. If you're doing something with BigInteger, it's likely that steps with larger values take more time, so a single cutoff value would not work (although you could consider some kind of dynamic cutoff value, based on the input).
Cheapest, easiest and best solution: run the code on a server.

Is there a way to find the total use time of my application

Is there library in Android that can provide me the total spend time of a user in my application without using my own time count?
I believe that Android OS is counting all application use time the same way as they count battery use ,network, etc..
If my assumptions are right, What I need is this system count for my application use time.
You can use Fabric (https://fabric.io/) there's some a lot useful tools that you can use, it also can track Daily Active User, Crash Reporting, etc.
They also provide us easy integration step, just take few minutes to integrate our system with Fabric.
The general approach to this is to:
Get the time at the start of your benchmark, say at the start of main().
Run your code.
Get the time at the end of your benchmark, say at the end of main().
Subtract the start time from the end time and convert into appropriate units.
A simpler way is this.
long startTime = System.nanoTime();
.....your program....
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println(totalTime);

Get Accurate UTC Time in Android

Okay so this might be basic but unfortunately I haven't found anything yet to help with this.
I'd like certain functionality to only happen in Android during a time frame that is specific to UTC/GMT Time.
How do you do this? I tried using System.currentTimeMillis() but if you change the time on an Android Device in the settings, this will also change System.currentTimeMillis().
I'd like to grab a time that is equal to UTC/GMT AND is independent of the Android Device Settings clock, so if the clock is changed on the device it won't interfere.
Any thoughts?
Thanks!
Christopher Steven
time.nist.gov is your friend if you want a truly accurate time.*
String TIME_SERVER = "time.nist.gov";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
NtpV3Packet message = timeInfo.getMessage();
//get the utc long from the server
long serverTime = message.getTransmitTimeStamp().getTime();
(Be sure to bundle all this in a thread if you're running on Android!)
One thing that I like to do is to take the difference between the server time and system time and store that for future use. In short, as long as the system time isn't fiddled with, you don't have to do multiple time calls. You can just take system time and change it based on the difference.
*you will need apache commons for this to work.
You need a time service from Internet. you can get the real time from time server NIST
apache-commons has a TimeInfo class to get NTP date
Example: NTPClient
System.nanoTime() returns the number of nanoseconds since the start up time, and is therefore not be susceptible to system clock changes.
At the startup use:
long startTime = System.TimeInMillis();
long nanoToDeduct = System.nanoTime();
Then at any point in time you can get the current time of the program as the clock was set at the startup of the program with
long currentTime = startTime - timeToDeduct + System.nanoTime();

Measuring time differences using System.currentTimeMillis()

I have a simple java program, and I want to know the time difference between some set of operations. For this question the details are not important, but let us take the following scenario.
long beginTime = System.currentTimeMillis();
//Some operations. Let us asssume some database operations etc. which are time consuming.
//
long endTime = System.currentTimeMillis();
long difference = endTime - beginTime;
When the code is run on a machine, how reliable will the difference be?
Let us say, that the processor starts executing some instructions from my code, then gives context to another process, which executes for some time, and then comes back to execute instructions related to this java process.
So, the time difference should depend on the current state of my machine, i.e. how many processes are running etc? So, in profiling time it takes for some operations to run, is this mechanism not reliable?
The granularity of System.currentTimeMillis() depends on the implementation and on the Operating system and is usually around 10 ms.
Instead use the System.nanoTime() which returns the current value of the most precise available system timer, in nanoseconds. Note that you can only use this to calculate elapsed time, you cannot use its value as an absolute time.
Example:
long startTime = System.nanoTime();
// do something you want to measure
long elapsedTimeNs = System.nanoTime() - startTime;
I think your code will do just fine as same is used in several projects. I don't think that if your code calls some other database process etc then it has any effect on your time. It should work fine in that case too.
Ex.
Main Process Started
long beginTime = System.currentTimeMillis();
.
.
.
Called another process (DB or command etc) -> (Another Process start)
.
<Now in this time main process is waiting> .
.
.
Returned from process <- (Another Process end)
.
.
long endTime = System.currentTimeMillis();
long difference = endTime - beginTime;
Now this difference will be total time taken for main process including time taken by another process. THis timing is in reference to the machine of main process & that is fine.

running loop for 5 minutes

I have a requirment to run a while loop the 5 min.
I looked for the timer api but I could not found to do this.
Can any one provide a code snipet for this.
Thanks
The easiest way will be to just check how much time has elapsed on each iteration. Example:
final long NANOSEC_PER_SEC = 1000l*1000*1000;
long startTime = System.nanoTime();
while ((System.nanoTime()-startTime)< 5*60*NANOSEC_PER_SEC){
// do stuff
}
This will run the loop, until more than 5 minutes have elapsed.
Notes:
The current loop iteration will always complete, so in practice it will always run for a bit more than 5 minutes.
For this application System.nanoTime() is more suitable than System.currentTimeMillis() because the latter will change if the computer's system clock is adjusted, thus throwing off the calculation. Thanks to Shloim for pointing this out.
This loop will run for 5 minutes. It will not be effected by changes made to the computer's date/time (either by user or by NTP).
long endTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(5L, TimeUnit.MINUTES);
while ( System.nanoTime() < endTime ){
// do whatever
}
Other methods like System.currentTimeMillis() should be avoided, because they rely on the computer date/time.
Because you are talking about the timer API I guess what you are after is a delay instead of a "loop running for 5min". If this is the case you could use something like Thread.sleep(..) which would allow to let the CPU do more usefull stuff that busy-waiting. Or at least save some energy and the planet.

Categories