I am a newbie in Java. I have done following coding.
class TimeComplex{
public static void main(String []args){
long startTime, stopTime, elapsedTime;
//first call
startTime = System.currentTimeMillis();
System.out.println("\nstart time : " + startTime + "\n");
calcForLoop();
stopTime = System.currentTimeMillis();
System.out.println("stop time : " + stopTime + "\n");
elapsedTime = stopTime - startTime;
System.out.println("\t1st loop execution time : " + elapsedTime+ "\n");
//second call
startTime = System.currentTimeMillis();
System.out.println("start time : " + startTime + "\n");
calcForLoop();
stopTime = System.currentTimeMillis();
System.out.println("stop time : " + stopTime + "\n");
elapsedTime = stopTime - startTime;
System.out.println("\t2nd loop execution time : " + elapsedTime + "\n");
//third call
startTime = System.currentTimeMillis();
System.out.println("start time : " + startTime + "\n");
calcForLoop();
stopTime = System.currentTimeMillis();
System.out.println("stop time : " + stopTime + "\n");
elapsedTime = stopTime - startTime;
System.out.println("\t3rd loop execution time : " + elapsedTime + "\n");
}
static void calcForLoop(){
for(long i = 12_85_47_75_807L; i > 0; i--);
}
}
The code runs a for-loop for a long period of time just to increase the execution time of the program. When the calcForLoop() is called for the first time the execution time of the program is maximum when the same method is called for the second time the program takes lesser time than the first call and the third call to the method calcForLoop() is less than or equal to the second execution time. I ran this program for 5-6 times and the I got the same pattern of execution time.
My question is why does this happen when the code to execute remains same for all the three time. Is there any code optimization that takes place by the compiler or it is dependent on the operating system environment. What sort of optimization is done by compiler when there is repeated execution of the same block of code like in this case?
The JIT (just in time) compiler compiles code that the JVM detects is being executed a lot, which accounts for the increase in performance. There may actually be a brief reduction in performance while such compilation is taking place.
It is usual to allow for this effect in performance testing - you execute the code a few thousand times, then start your benchmark.
Loop nest optimization is an optimization technique that applies a set of loop transformations for the purpose of locality optimization or parallelization. One classical usage is to reduce memory access latency or the cache bandwidth necessary due to cache reuse for some common linear algebra algorithms.
If you want to be more accurate in measuring the elapsed time you must use System.nanoTime() instead of using System.currentTimeMillis().
And of course what Bohemian mentioned about JIT do comes into picture.
Related
This question already has answers here:
How do I write a correct micro-benchmark in Java?
(11 answers)
Closed 3 years ago.
In my code, both for loops have the same time complexity and same operation, however the second nested for loop takes almost 40 times more time than first one. Why is this happening?
I am using javac compiler and running my code in windows command prompt.
import java.util.concurrent.TimeUnit;
class Elapsedtime
{
public static void main(String[] args) throws InterruptedException
{
int i,j,t,a;
long startTime = System.nanoTime();
for(i=0;i<1000000000;i++)
{
for(j=0;j<1000000000;j++)
{
a=j;
}
}
long endTime = System.nanoTime();
long timeElapsed = endTime - startTime;
System.out.println("Execution time in nanoseconds : " + timeElapsed + " ns.");
System.out.println("Execution time in milliseconds : " + timeElapsed / 1000000 + " ms.");
startTime = System.nanoTime();
for(t=0;t<1;t++)
{
for(i=0;i<1000000000;i++)
{
for(j=0;j<1000000000;j++)
{
a=j;
}
}
}
endTime = System.nanoTime();
timeElapsed = endTime - startTime;
System.out.println("Execution time in nanoseconds : " + timeElapsed + " ns.");
System.out.println("Execution time in milliseconds : " + timeElapsed / 1000000 + " ms.");
}
}
I am getting the following output.
Execution time in nanoseconds : 17963700 ns. Execution time in
milliseconds : 17 ms. Execution time in nanoseconds : 549485500 ns.
Execution time in milliseconds : 549 ms.
but I don't expect much difference.
It is possible that during the first nested loop the optimizing compiler creates better code because it determines that there are going to be many iterations. The second loop will already run the optimized code.
You can test this by reversing the order of the two loops, still the first one will likely be slower.
I am trying to calculate the time consumed by the program. But what is the difference between the two methods displayed below?
System.currentTimeMillis() % 1000
System.currentTimeMillis() / 1000
I assume by the fact that you're dividing by 1000 you want it in seconds?
Regardless, the modulus operator % is not what you want here, it gives you the remainder of the division by the second operand.
To get the runtime of some code, get the current time before execution, and after execution. The runtime will the the difference between the two.
System timeBefore = System.currentTimeMillis();
//PUT CODE HERE
System timeAfter = System.currentTimeMillis();
System timeDelta = timeAfter = timeBefore;
System.out.println("Runtime was " + timeDelta + " millis"); //display milliseconds
System.out.println("Runtime was " + (timeDelta / 1000) + " seconds"); //display seconds
You may want to try something like this:
public static void main(String[] args) throws InterruptedException{
long t1 = System.nanoTime();
Thread.sleep(3000L);//do your work here
long t2 = System.nanoTime();
long result = t2 - t1;
result = result / 1000000000;
System.out.println(result);
}
This will give you time in seconds...
Output:
3
Explanation of the two methods
System.currentTimeMillis() / 1000
/ is the division operator. It will return you the result of System.currentTimeMillis() divided by 1000. This is often used to convert miliseconds to seconds.
System.currentTimeMillis() % 1000
% is the remainder operator.
It will return the remainder that is left after the division by 1000 (modulus).
Oracle provides a full list of Java-Operators.
Example for the question from the title
If you want to get the total uptime off your application, you can easily receive it from the Java Runtime:
ManagementFactory.getRuntimeMXBean().getUptime()
This will return the runtime of your programm in milliseconds. By dividing it with 1000 you will get the seconds your programm is running.
Advantage:
You don't have to handle the time measurement yourself
in my run method of a game loop I tried to print the time the program has been running in java. I simply tried System.out.println(System.nanoTime() / 1000000); because that's how many milliseconds are in a second.(if you didn't know) It prints the seconds near the end but I wanted exact seconds for testing purposes. I searched online and someone suggested using the same formula I thought of. Can anyone give an exact one?
Store previous time in a private member.
private long previousTime;
Initialize it in the constructor.
previousTime = System.currentTimeMillis();
Compare it with current time in run method (each iteration of game loop)
long currentTime = System.currentTimeMillis();
double elapsedTime = (currentTime - previousTime) / 1000.0;
System.out.println("Time in seconds : " + elapsedTime);
previousTime = currentTime;
In addition to the other answers provided, you could use a standard library StopWatch, like the one provided by Google's Guava API:
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
calculate();
stopwatch.stop(); // optional
long Seconds= stopwatch.elapsedMillis() / 1000000; // equals 1 second
You can use System.currentTimeMillis to get the current time in milliseconds.
If you pick this value at the start of your application and at the end, the subtraction of both values will give you the time your application was running.
final long start = System.currentTimeMillis();
// your code here...
final long end = System.currentTimeMillis();
System.out.println("The program was running: " + (end-start) + "ms.");
If you want it in seconds, just divide it with 1000 like you mentioned.
System.out.println("The program was running: " + ((double)(end-start)/1000.0d) + "ms.");
I have a BFS algorithm to solve the 8-Puzzle, and one of the project requirements is to output the amount of time it takes to find the shallowest solution.
I am using System.nanoTime() to keep track of the applications run time because it solves the majority of the given puzzles in well under a second.
The problem i am having is whem i convert my nanoTime to seconds, it displays in a weird format.
the following code is used:
final long startTime = System.nanoTime();
//algorithm code removed for simplicity this all functions correctly
final long duration = System.nanoTime() - startTime;
final double seconds = ((double)duration / 1000000000);
System.out.println("Nano time total: " + duration);
System.out.println("solution Time : " + seconds + " Seconds");
This produces the output:
Nano time total: 916110
solution time : 9.1611E-4 Seconds
I have also tried using floats to represent the values.
is anybody able to provide a better way to convert/display, maybe use a format output statement?
Thanks for taking the time to read my question.
I think you need: DecimalFormat
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(seconds) + " Seconds");
System.out.format("solution Time : %f Seconds", seconds);
for the classic, non-exponential floating point number.
If I understand correctly, using System.nanoTime() is a more accurate way of keeping a marker to the current time than System.currentTimeInMillis(), even if the system time was changed. So why is it that when I convert the long value of nanoTime() to a Calendar object, the output is wrong?
import java.util.Calendar;
public class Test {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
System.out.println(c.get(Calendar.MONTH) + " " + c.get(Calendar.DATE) + " " + c.get(Calendar.YEAR) +
" " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND)
+ ":" + c.get(Calendar.MILLISECOND));
}
}
System.nanotime() javadoc suggests :
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
For example, to measure how long some code takes to execute:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;