I am working in a Java project and we are not using any profiling tool.
Is there a way to find out the time a method takes for execution without using any profiling tool?
Why dont you use something like:
int startTime = System.currentTimeMillis();
methodCall();
int endTime = System.currentTimeMillis();
int totalTime = endTime - startTime;
System.out.println("Time to complete: " + totalTime);
Then you could add the /1000 or whatever to format the time as you desire.
Catch System.currentTimeMillis() before start and at the end minus with System.currentTimeMillis().
You will be able to know how much time your method takes to execute.
void fun(){
long sTime=System.currentTimeMillis();
...
System.out.println("Time Taken to execute-"+System.currentTimeMillis()-sTime+" milis");
}
Here is a sample program to capture timings:
package com.quicklyjava;
public class Main {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// start time
long time = System.nanoTime();
for (int i = 0; i < 5; i++) {
System.out.println("Sleeping Zzzz... " + i);
Thread.sleep(1000);
}
long difference = System.nanoTime() - time;
System.out.println("It took " + difference + " nano seconds to finish");
}
}
And here is the output:
Sleeping Zzzz... 0
Sleeping Zzzz... 1
Sleeping Zzzz... 2
Sleeping Zzzz... 3
Sleeping Zzzz... 4
It took 5007507169 nano seconds to finish
Related
I want to be able to calculate remaining time of myHandler2.postDelayed(). I was using this answer but it returns wrong value. Here is my code where the startTime variable is:
public void attackOnChibi(ChibiCharacter cc, boolean able) {
runnable = () -> {
Log.i("a", "a");
};
if (able) {
startTime = System.nanoTime();
myHandler2.postDelayed(runnable, count += 2000);
}
if (!able) {
myHandler2.removeCallbacksAndMessages(null);
count = 0;
}
}
And the code when I calculates and displays this remaining time:
elapsedTime = System.nanoTime() - gs.enemies.get(gs.enemyId - 1).startTime;
remainingTime = gs.enemies.get(gs.enemyId - 1).count + 2000 - TimeUnit.MILLISECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS);
Log.i("elapsed/remaining", elapsedTime + " " + remainingTime);
Why it does not work? Help me please...
Here is a main that runs a simple counting loop three ways:
Single-threaded
2 threads using inline code that creates two distinct Thread objects
2 threads using instances of the CountingThread class that inherits from Thread
package main;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
demo();
}
public static void demo() {
final long limit = 100_000_000_000L;
long startTime = System.currenatTimeMillis();
for (long i = 0; i < limit; i++) {
// Nothing to see here, just counting
}
long endTime = System.currentTimeMillis();
System.out.println("Single threaded: Total execution time: " + (endTime - startTime) + " milliseconds.");
// Now try it in two threads. Each thread will perform 1/2 of the counting
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (long i = 0; i < limit/2; i++) {
// Nothing to see here, just counting
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (long i = limit/2; i < limit; i++) {
// Nothing to see here, just counting
}
}
});
startTime = System.currentTimeMillis();
t1.start();
t2.start();
// Join t1 until it ends, then join t2 until it ends. Note that t1 and t2 are running in parallel with this thread.
try {t1.join();} catch (InterruptedException e) {}
try {t2.join();} catch (InterruptedException e) {}
endTime = System.currentTimeMillis();
System.out.println("2 threaded using inline code: Total execution time: " + (endTime - startTime) + " milliseconds.");
// Now try it with 2 instances of the CountingThread class.
ArrayList<CountingThread> countingThreads = new ArrayList<CountingThread>();
int numberOfThreads = 2;
long increment = limit / numberOfThreads;
for (int i = 0; i < numberOfThreads; i++) {
long start, end;
start = i * increment;
end = start + increment;
countingThreads.add(new CountingThread(start, end));
}
// Launch all the threads to run in parallel
startTime = System.currentTimeMillis();
for (int i = 0; i < numberOfThreads; i++) {
countingThreads.get(i).run();
}
// Wait for all the threads to finish
for (int i = 0; i < numberOfThreads; i++) {
try {countingThreads.get(i).join();} catch(InterruptedException ex) {}
}
endTime = System.currentTimeMillis();
System.out.println(numberOfThreads + " threaded using classes: Total execution time: " + (endTime - startTime) + " milliseconds.");
}
}
Here is the class that inherits from Thread:
package main;
/**
* Count from one long int up to another long int. Really simple
*
*/
public class CountingThread extends Thread {
private long start, end;
public CountingThread(long start, long end) {
this.start = start;
this.end = end;
}
#Override
public void run() {
for(long i = start; i <= end; i++) {
}
// System.out.println("Thread counted from " + start + " to " + end);
}
}
Here is the output:
Single threaded: Total execution time: 40379 milliseconds.
2 threaded using inline code: Total execution time: 23312 milliseconds.
2 threaded using classes: Total execution time: 40358 milliseconds.
It seems like methods 2 and 3 should take about the same amount of time. What's up with that?
The machine has 4 cores.
You made a mistake and call #run instead of #start. Run method is executed in the same thread.
countingThreads.get(i).run();
I have a Runnable "NanoClock" class which keeps updating a private volatile double value in its run() method.
This class also has a getTime() method which returns the double value. Another class ("Master") is constructing the NanoClock class and creates a thread, as well as calling the start() method.
After it did this it calls the getTime() method several times (with a delay), but the value is not updating. What am I doing wrong?
NanoClock.java :
public class NanoClock implements Runnable {
private volatile boolean running;
private volatile double time;
public NanoClock() {
time = System.currentTimeMillis();
}
#Override
public void run() {
running = true;
while(running) {
try {
if(System.currentTimeMillis() > time) {
time = System.currentTimeMillis();
}
//This returns the updated value continuously when commented out
//System.out.println("Time: " + String.format("%.6f", unix_time));
Thread.sleep(2000);
} catch(Exception exc) {
exc.printStackTrace();
System.exit(1);
}
}
}
public double getTime() {
return time;
}
public void end() {
running = false;
}
}
Master.java:
public class Master {
public static void main(String[] args) {
try {
NanoClock nClock = new NanoClock();
Thread clockThread = new Thread(new NanoClock());
clockThread.setPriority(10);
clockThread.start();
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
//MY_ISSUE: This cannot stop the while loop - I tested it with
//the println in the NanoClock class.
nClock.end();
System.out.println("Done!");
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
You've got two instances of NanoClock: one of them is an anonymous new NanoClock() which, as the Runnable in your other thread is happily keeping time in the backgound; the other is nClock, which is sitting idly by in the foreground in your main thread.
nClock should have been the Runnable in that other thread:
Thread clockThread = new Thread(nClock); // not new NanoClock()
This may not be the entire solution, but it should be a big step in the right direction.
System.currentTimeMillis() returns a long, but you store it in a double, which causes a loss of precision. When you change the member time (and also the return type of its getter) to a long you should get the expected result.
As a rule of thumb: When working with time units long is most appropriate datatype most of the time. Floating point numbers are not suitable to store precise results.
Thread.sleep(2000);
System.out.println("Time: " + nClock.getTime());
the for in main() must be sleep(2000)
If the code below will take 2 seconds, then the time will change.
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
However a for loop with 10 iterations and a system.out will not even take a millisecond so it will not change.
Why 2 seconds? because you have a Thread.sleep in your runnable code.
Thread.sleep(2000);
Which means, the next update will be in 2 seconds.
And use System.nanoTime() instead of System.currentTimeMillis() since you really wanted nano time not millis.
Updated:
In my machine
public static void main(String args[]) {
long start = System.currentTimeMillis();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.currentTimeMillis();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
Result, there is no difference in the start time and end time
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1499592836298
End = 1499592836298
That code block executed so fast that it did not take even a single millisecond. Depending on the timing, it may take 1 millisecond.
Changing it to System.nanoTime()
public static void main(String args[]) {
long start = System.nanoTime();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.nanoTime();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
Result, there is a difference in the start time and end time.
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1012518090518837
End = 1012518091012960
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.
for(int i = 1; i < 10000; i++) {
Command nextCommand = getNextCommandToExecute();
}
I want to run the above program for 60 minutes. So instead of for loop I need to do something like-
long startTime = System.nanoTime();
do{
Command nextCommand = getNextCommandToExecute();
} while (durationOfTime is 60 minutes);
But I am not sure, how should I make this program to run for 60 miniutes.
Launch a background thread that sleeps for 60 minutes and exits:
Runnable r = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(60 * 60 * 1000L);
}
catch (InterruptedException e) {
// ignore: we'll exit anyway
}
System.exit(0);
}
}
new Thread(r).start();
<your original code here>
long startTime = System.currentTimeMillis();
do
{
//stuff
} while (System.currentTimeMillis() - startTime < 1000*60*60);
try the following:
long startTime = System.currentTimeMillis();
long endTime = startTime + (60*60*1000);
while(System.currentTimeMillis() <= endTime) {
Command nextCommand = getNextCommandToExecute();
}
One drawback with this method is if the Command you are trying to execute runs past the 60 minute timer or never finishes at all. If this behavior is not allowed, you are better off implementing a thread that interrupts whatever thread is running this loop.
long startTime = System.currentTimeMillis();
do{
Command nextCommand = getNextCommandToExecute();
}while (startTime < startTime+60*60*1000);
You could use:
long startTime = System.nanoTime();
do {
Command nextCommand = getNextCommandToExecute();
} while ((System.nanoTime() - startTime) < 60 * 60 * 1000000000L);
Please note System.nanoTime() is slightly different from using System.currentTimeMillis() not only in the scale, but also in what it measures: System.nanoTime() is the elapsed time, and System.currentTimeMillis() is the system time (wall clock). If the system time changes, System.currentTimeMillis() doesn't work as expected. (This doesn't apply to summertime change however, as the returned value is UTC / GMT.)
1000000000L nanoseconds is one second. Please note the L for long. In Java 7 you could also write the more readable 1_000_000_000L.