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
});
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...
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);
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.
This is code which I have written to time how long it takes to perform a selection sort:
static public String [ ] selectionSort(String [ ] wordlist)
{
for (int i = 1; i < wordlist.length; i++)
{
int s = i-1;
for (int j = i; j < wordlist.length; j++)
{
if (wordlist[j].compareTo(wordlist[s]) < 0)
{
s = j;
}
}
String temp = wordlist[i-1];
wordlist[i-1] = wordlist[s];
wordlist[s] = temp;
}
return wordlist;
}
static public String [ ] timedSelectionSort(String [ ] wordlist)
{
long startTime = 0;
long stopTime = 0;
long elapsedMillis = 0;
long elapsedSec = 0;
long elapsedMin = 0;
startTime = System.currentTimeMillis();
wordlist = selectionSort(wordlist);
stopTime = System.currentTimeMillis();
elapsedMillis = stopTime-startTime;
elapsedSec = elapsedMillis/1000;
elapsedMin = elapsedMillis/60000;
System.out.printf("File reading took %d minutes and %s secs and %d milliseconds to execute\n",
elapsedMin,elapsedSec%60, elapsedMillis%1000);
System.out.println("Read " + wordlist.length + " strings.");
return wordlist;
}
I have to also time a how long it takes to make an arraylist object containing all of the strings in an array (my attempt is below)
static public ArrayList<String> makeArrayListClassObject(String [ ] wordlist)
{
long startTime = 0;
long stopTime = 0;
long elapsedMillis = 0;
long elapsedSec = 0;
long elapsedMin = 0;
startTime = System.currentTimeMillis();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(wordlist));
stopTime = System.currentTimeMillis();
elapsedMillis = stopTime-startTime;
elapsedSec = elapsedMillis/1000;
elapsedMin = elapsedMillis/60000;
System.out.printf("File reading took %d minutes and %s secs and %d milliseconds to execute\n",
elapsedMin,elapsedSec%60, elapsedMillis%1000);
System.out.println("Read " + wordlist.length + " strings.");
return stringList;
}
as well as time how long it takes to sort the arraylist object using the Collections.sort( ) method. I have made the method (see below) but I don't know how to time it
static public void collectionsClassSort(ArrayList<String> arraylist)
{
Collections.sort(arraylist);
}
I guess my questions are:
1. Is there a way to use the same method to time these two methods the way I timed the first method?
2. If not, how can I time these two methods?
EDIT: the timed collections sort now works, but the timed building of the arraylist still does not. meaning that the timer says that the method took 0 minutes, 0 seconds, and 0 milliseconds to execute
This is the updated code for that:
static public ArrayList<String> makeArrayListClassObject(String [ ] wordlist)
{
long startTime = 0;
long stopTime = 0;
long elapsedMillis = 0;
long elapsedSec = 0;
long elapsedMin = 0;
startTime = System.currentTimeMillis();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(wordlist));
stopTime = System.currentTimeMillis();
elapsedMillis = stopTime-startTime;
elapsedSec = elapsedMillis/1000;
elapsedMin = elapsedMillis/60000;
System.out.printf("File reading took %d minutes and %s secs and %d milliseconds to execute\n",
elapsedMin,elapsedSec%60, elapsedMillis%1000);
return stringList;
}
Why can't you just use something like this,
startTime = System.currentTimeMillis();
Collections.sort(arraylist);
stopTime = System.currentTimeMillis();
Its samething that you used above.
You need to distinguish between "doesn't work" and "doesn't produce a meaningful result".
It seems that your wordList string array is not large enough to notice time difference.
Two suggestions:
Test it with a much bigger array: hundreds of thousands of words (see my test code at the bottom)
Use System.nanoTime() that should yield better precision (see the explanation below).
From David Holmes' Weblog:
The absolute "time-of-day" clock is represented by the
System.currentTimeMillis() method, that returns a millisecond
representation of wall-clock time in milliseconds since the epoch. As
such it uses the operating system's "time of day" clock. The update
resolution of this clock is often the same as the timer interrupt (eg.
10ms), but on some systems is fixed, independent of the interrupt
rate.
The relative-time clock is represented by the System.nanoTime() method
that returns a "free-running" time in nanoseconds. This time is useful
only for comparison with other nanoTime values. The nanoTime method
uses the highest resolution clock available on the platform, and while
its return value is in nanoseconds, the update resolution is typically
only microseconds. However, on some systems there is no choice but to
use the same clock source as for currentTimeMillis() - fortunately
this is rare and mostly affects old Linux systems, and Windows 98.
You should always try to use nanoTime to do timing measurement or
calculation (and yes there are JDK API's that don't do this), in the
hope that it will have a better resolution than currentTimeMillis.
The following code produced "2" on my system:
import java.util.*;
public class ArrayTime {
public static void main(String[] args) {
String[] wordList = new String [600000];
for(int i=0; i<wordList.length; ++i)
wordList[i] = "" + i;
long start = System.currentTimeMillis();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(wordList));
long elapsedTime = System.currentTimeMillis() - start;
System.out.println(elapsedTime);
}
}
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.