Calculate elapsed time with System.currentTimeMillis() in java - java

For some reason I can get the start time and the stop time in my program (which is normally a difference of 3 milliseconds) but when I print the result of the getElapsedTime() method it always comes back with 0. Above the listed code is the creation of a StopWatch object named sortTime.
Perhaps there is a problem with rounding?
Perhaps there is a problem with the getElapsedTime() method itself?
System.out.println(sortTime.start()); // Start Timer
java.util.Arrays.sort(numbers); // Sort the array
System.out.println(sortTime.stop());// stop timer
System.out.println("the elapsed time is: " + sortTime.getElapsedTime());
}
} //end of main class (used for testing)
//Define Class
class StopWatch {
long startTime;
long endTime;
//Constructors
public StopWatch () {
}
//Methods
long start() {
long startTime = System.currentTimeMillis();
return startTime;
}
long stop() {
long endTime = System.currentTimeMillis();
return endTime;
}
long getElapsedTime() {
return (endTime - startTime);
}
}
For example, when I run the program the result is:
1442877972466
1442877972469
the elapsed time is: 0

You are creating local variables with the same name as class variables:
long start() {
long startTime = System.currentTimeMillis();
return startTime;
}
The use of long startTime in this function makes a local variable that is different from the class member named startTime. Change this to:
long start() {
startTime = System.currentTimeMillis();
return startTime;
}

startTime and endTime have been redeclared/shadowed as local variables, leaving the instance fields with their default values (of 0)
long start() {
long startTime = System.currentTimeMillis();
return startTime;
}
long stop() {
long endTime = System.currentTimeMillis();
return endTime;
}
Instead, make use of the instance fields...
long start() {
startTime = System.currentTimeMillis();
return startTime;
}
long stop() {
endTime = System.currentTimeMillis();
return endTime;
}

Related

a method to get the runtime of another method

I know how to get the runtime of a method from here
How do I time a method's execution in Java?
Now I need to get the run time multiple times, so is there a way to make something like
public long exTime(methodToTime())
long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();
long duration = (endTime - startTime);
Thanks for your help
edit: to be more specific, my current code is
long startTime0 = System.nanoTime();
revealStr("1001*00*10");
long endTime0 = System.nanoTime();
long duration0 = (endTime0 - startTime0);
System.out.println("The runtime is " + endTime0);
System.out.println("10**01*1*0");
long startTime1 = System.nanoTime();
revealStr("10**01*1*0");
long endTime1 = System.nanoTime();
long duration1 = (endTime0 - startTime1);
System.out.println("The runtime is " + endTime1);
System.out.println("0*1*0**0**");
long startTime2 = System.nanoTime();
revealStr("0*1*0**0**");
long endTime2 = System.nanoTime();
long duration2 = (endTime2 - startTime2);
System.out.println("The runtime is " + endTime2);
System.out.println("****1*1***");
long startTime3 = System.nanoTime();
revealStr("****1*1***");
long endTime3 = System.nanoTime();
long duration3 = (endTime3 - startTime3);
System.out.println("The runtime is " + endTime3);
System.out.println("**********");
long startTime4 = System.nanoTime();
revealStr("**********");
long endTime4 = System.nanoTime();
long duration4 = (endTime4 - startTime4);
System.out.println("The runtime is " + endTime0);
which is repetitive and redundant
This is a util method I used to compare the performance of two method.
public static void testPerformance(long loopTime, Runnable r1,Runnable r2){
long startTime;
long endTime;
startTime=System.currentTimeMillis();
for (int i = 0; i < loopTime; i++) {
r1.run();
}
endTime=System.currentTimeMillis();
System.out.printf("loop %d times, total spend %d s, each spend %f ms\n",loopTime,(endTime-startTime)/1000,(double)(endTime-startTime)/loopTime);
startTime=System.currentTimeMillis();
for (int i = 0; i < loopTime; i++) {
r2.run();
}
endTime=System.currentTimeMillis();
System.out.printf("loop %d times, total spend %d s, each spend %f ms\n",loopTime,(endTime-startTime)/1000,(double)(endTime-startTime)/loopTime);
}
You can use like this:
PerformanceUtils.testPerformance(loopTime,()->{
//do some thing
},()->{
//do some thing
});

How can I remove duplicated from my code in Java?

I wrote a test that will run recursion Fibonacci for 40 and run memoization recursion Fibonacci for 40 and compare the time to be at least one order of magnitude different. This is what I get so far:
#Test
void MemoizedMagnitudeDifferentFromRecursion(){
Fibonacci simpleRecursiveFibonacci = new SimpleRecursiveFibonacci();
Fibonacci memoizedRecursiveFibonacci = new MemoizedRecursiveFibonacci();
int n = 40;
long recursionStartTime = System.nanoTime();
simpleRecursiveFibonacci.fibonacci(n);
long recursionTime = System.nanoTime() - recursionStartTime;
//The code below does the same as the code above, how can I remove duplicated code?
long memoizedStartTime = System.nanoTime();
memoizedRecursiveFibonacci.fibonacci(n);
long memoizedTime = System.nanoTime() - memoizedStartTime;
assertTrue(recursionTime/memoizedTime > 1);
}
Extract the logic to a function and pass the logic to be run as a Runnable. Let the function run the piece of logic passed in and return the time it took to run it.
private long execute(Runnable runnable) {
long startTime = System.nanoTime();
runnable.run();
return System.nanoTime() - startTime;
}
Call it as
long recursionTime = execute(() -> simpleRecursiveFibonacci.fibonacci(n));
long memoizedTime = execute(() -> memoizedRecursiveFibonacci.fibonacci(n));
assertTrue(recursionTime/memoizedTime > 1);
One more option (as suggested by SystemGlitch#) is to pass an instance of Fibonacci and an int and call fibonacci inside the method.
private long execute(Fibonacci fibonacciInstance, int n) {
long startTime = System.nanoTime();
fibonacciInstance.fibonacci(n);
return System.nanoTime() - startTime;
}
Call it as
long recursionTime = execute(simpleRecursiveFibonacci, n);
long memoizedTime = execute(memoizedRecursiveFibonacci, n);
assertTrue(recursionTime/memoizedTime > 1);

How to calculate the execution time of a Loop for one iteration?

Below is My code:
public class FindTime {
HashSet<String> hashSet = new HashSet<>();
long m1() {
hashSet.add("hai");
hashSet.add("me");
hashSet.add("you ");
hashSet.add("I");
hashSet.add("Us");
Iterator it = hashSet.iterator();
long startTime = System.currentTimeMillis();
while (it.hasNext()) {
System.out.println(it.next());
}
return startTime;
}
public static void main(String[] args) {
FindTime ft = new FindTime();
long startTime = ft.m1();
System.out.println("startTime" + startTime);
long endTime = System.currentTimeMillis();
System.out.println("End time" + endTime);
System.out.println("d/W" + (endTime - startTime));
}
}
I don't know is that one is correct way or not.My requirement is
"I want to calculate time taken to Iterate a HashSet".
To be more precise use System.nanoTime()
public class FindTime {
HashSet<String> hashSet = new HashSet<>();
long m1()
{
hashSet.add("hai");
hashSet.add("me");
hashSet.add("you ");
hashSet.add("I");
hashSet.add("Us");
Iterator it = hashSet.iterator();
long startTime = System.nanoTime();
while (it.hasNext()) {
System.out.println(it.next());
}
return startTime;
}
public static void main(String[] args) {
FindTime ft = new FindTime();
long startTime = ft.m1();
long endTime = System.nanoTime(); //CALCULATE THE END TIME BEFORE PRINTING START TIME
//BECAUSE PRINT OPERATION WILL ALSO TAKE TIME THAT WILL BE ADDED TO DIFFERENCE
System.out.println("Start time in nano seconds" + startTime); //No need because you actually need difference
System.out.println("End time in nano seconds" + endTime);
System.out.println("Difference in Nano Seconds" + (endTime - startTime));
//long microsecondsTime = (end - start) / 1000; //If you need in microseconds
}
}
Your code is correct. You've calculated the time which taken for iterating and printing the output in console. Print may take more time than iteration.
You may have also returned the execution time by
return System.currentTimeMillis()- startTime;
See Also : Do not use System.out.println in server side code
As you telling you need time to take only for iterate not for insertion then you can use it like
long m1() {
hashSet.add("hai");
hashSet.add("me");
hashSet.add("you ");
hashSet.add("I");
hashSet.add("Us");
Iterator it = hashSet.iterator();
long startTime = System.nanoTime();
while (it.hasNext()) {
System.out.println(it.next());
}
long endTime = System.nanoTime();
System.out.println("time taken in nano seconds" + endTime-startTime);
return endTime-startTime;
}
reason is if you take time into your main function then it will also calculate the time for insertion.
Yes I am agree that it will not affect too much but we know that is not right thing to do.Even here I am printing so here also it will add the printing time that is not exactly correct.

Infinite for loop

This code works fine:
public class Main {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000;
long index = 0;
while (true) {
double x = Math.sqrt(index);
long now = System.currentTimeMillis();
if (now > endTime) {
break;
}
index++;
}
System.out.println(index + " loops in one minute.");
}
}
But then, I tried rewriting it into a for loop, and it gets stuck in an infinite loop.
public class Main {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000;
int i = 0;
for (long now = 0; now < endTime; i++) {
Math.sqrt(i);
now = System.currentTimeMillis();
System.out.println("now" + now);
System.out.println("end" + endTime);
}
}
System.out.println(i+"calculations done in one minute");
}
Your second example is not an infinite loop, just wait 1 minute.
long endTime = startTime + 60000;
set the endTime to 60000 milliseconds in the future, that means 60 seconds, means 1 minute.
The standard output is just printing extremely fast.
Put a Thread.sleep(1000L) in the loop and you will see 61 statements being printed before it ends.
long endTime = 1378140843604L; // for example
for (long now = 0; now < endTime; i++) {
now = System.currentTimeMillis(); // will be 1378140783604, 1378140784604, 1378140785604 and so on
System.out.println("now" + now);
System.out.println("end" + endTime);
Thread.sleep(1000L);
}
This worked for me:
public class Main {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000;
int i = 0;
for (long now = 0; now < endTime; i++) {
Math.sqrt(i);
now = System.currentTimeMillis();
System.out.println("now" + now);
System.out.println("end" + endTime);
}
System.out.println(i+"calculations done in one minute");
}
}
The only difference between mine an yours is where I put this: (yours is outside the main method)
System.out.println(i+"calculations done in one minute");
You should also be aware it take just microseconds to run through the loop so you're getting a huge output.

How to test a timer?

I would like to write a test for a method, that calls observers in a specific intervall, so that they will execute a method. The timer-object runs in its own thread.
Method of timer to be tested
private long waitTime;
public Metronome(int bpm) {
this.bpm = bpm;
this.waitTime = calculateWaitTime();
this.running = false;
}
public void run() {
long startTime = 0, estimatedTime = 0, threadSleepTime = 0;
running = true;
while (running) {
startTime = System.nanoTime();
tick();// notify observers here
estimatedTime = System.nanoTime() - startTime;
threadSleepTime = waitTime -estimatedTime;
threadSleepTime = threadSleepTime < 0 ? 0 : threadSleepTime;
try {
Thread.sleep(threadSleepTime / 1000000l);
} catch (InterruptedException e) {
// sth went wrong
}
}
}
Snippet from my testclass
private int ticks;
private long startTime;
private long stopTime;
#Test
public void tickTest(){
metronome.setBpm(600);
startTime = System.nanoTime();
metronome.run();
long duration = stopTime - startTime;
long lowThreshold = 800000000;
long highThreshold = 900000000;
System.out.println(duration);
assertTrue(lowThreshold < duration);
assertTrue(duration <= highThreshold);
}
#Override
public void update(Observable o, Object arg) {
ticks ++;
if(ticks == 10){
metronome.stop();
stopTime = System.nanoTime();
}
}
Right now, my testclass registers as an observer at the object in question, so that i can count the number of times tick() was executed. The test measures the time before and after the execution, but it feels awkward to me, to test the behaviour this way.
Any suggestions for improving the test?
Sometimes the solution is to use something from a standard library that is sufficiently simple such that it does not need to be tested. I think SchedulerExecuterService will do the trick for replacing the home made Timer being tested here. Note that it is pretty rare to be bit by a bug in library code, but they do exist.
In general though, I think it is okay to create a helper class or use a mocking framework (Mockito) to do something simple like counting "ticks".
P.S. You can replace Thread.sleep(threadSleepTime / 1000000l) with TimeUnit.NANOSECONDS.sleep(threadSleepTime) ... which moves some logic from your code into the standard library.
Based on your comments I changed my code. Instead of implementing the Observer-interface in my testclass, I now created a private class, that implements the interface an registers at my timer.
Thanks for your time and thoughts.
Here is what the code now looks like:
revised testcode
#Test(timeout = 2000)
public void tickTest(){
long lowThreshold = 400000000;
long highThreshold = 600000000;
TickCounter counter = new TickCounter();
metronome.addObserver(counter);
metronome.setBpm(600);
startTime = System.nanoTime();
metronome.run();
long duration = System.nanoTime() - startTime;
assertTrue(lowThreshold <= duration);
assertTrue(duration <= highThreshold);
}
private class TickCounter implements Observer{
private int ticks;
public TickCounter(){
ticks = 0;
}
#Override
public void update(Observable o, Object arg) {
ticks++;
if(ticks == 5){
metronome.stop();
}
}
}
snippet from my revised timer
private long expectedTime; // calculated when bpm of timer is set
#Override
public void run() {
long startTime = 0, elapsedTime = 0, threadSleepTime = 0;
running = true;
while (running) {
startTime = System.nanoTime();
tick();
elapsedTime = System.nanoTime() - startTime;
threadSleepTime = expectedTime - elapsedTime;
threadSleepTime = threadSleepTime < 0 ? 0 : threadSleepTime;
try { TimeUnit.NANOSECONDS.sleep(threadSleepTime); } catch (Exception e) { }
}
}
My biggest issue might have been, that I implemented the observer-interface in my JUnit testcase. So I created a private observer, that specifically counts the number of times, the tick was executed. The counter then stops my timer.
The testmethod measures the timing and asserts, that the needed time is somewhere between my defined limits.
It depends on how accurately you need to measure the time.
If you feel that it's "awkward" is that because you're not sure that the measurement is accurate enough? Do you fear that the OS is getting in the way with overhead?
If so, you may need an external timing board that's synchronized to an accurate source (GPS, atomic standard, etc.) to either test your code, or possibly to provide the trigger for your firing event.
Try this. You also need the time you are expecting. The expected time will be 1000000000/n where n is the number of times your timer needs to tick() per second.
public void run(){
long time = System.nanotime();
long elapsedTime = 0;
// Hope you need to tick 30 times per second
long expectedTime = 1000000000/30;
long waitTime = 0;
while (running){
tick();
elapsedTime = System.nanotime()-time;
waitTime = expectedTime-elapsedTime();
if (waitTime>0){
try { Thread.sleep(waitTime) } catch (Exception e){}
}
time = System.nanotime();
}
}

Categories