Calculating elapsed time of method - java

I'm trying to record the elapsed time for my method in milliseconds. Could someone tell me what I'm doing wrong?
public static void main(String[] args)
{
double pi = computePi(10000);
System.out.println(pi);
System.out.println(startTime - endTime);
}
long startTime = System.currentTimeMillis();
public static double computePi(int count)
{
double pi = 0;
for(int i = 0; i < count; i++)
{
pi += Math.pow(-1,i)/(2*i+1);
long endTime = System.currentTimeMillis();
}
return pi * 4;
return startTime - endTime;
}
}

The computation should be just before and after the method call. It should be endTime-startTime.
public static void main(String[] args)
{
long startTime = System.currentTimeMillis();
double pi = computePi(10000);
long endTime = System.currentTimeMillis();
System.out.println(pi);
System.out.println(endTime- startTime);
}

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
});

JAVA, got wrong value when using LongAdder in multi-thread

I am doing this exercise:
Generate 1,000 threads, each of which increments a counter
100,000 times. Compare the performance of using AtomicLong
versus LongAdder.
And the following is my implementation:
import java.io.*;
import java.util.*;
import java.nio.file.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class AtomicLongVsLongAddr {
// 9. Generate 1,000 threads, each of which increments a counter
// 100,000 times. Compare the performance of using AtomicLong
// versus LongAdder.
AtomicLong al = new AtomicLong(0);
LongAdder la = new LongAdder();
public class AtomicLongThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 100000; i ++) {
al.incrementAndGet();
}
}
}
public class LongAdderThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 100000; i ++) {
la.increment();
}
}
}
public static void main(String[] args) {
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
(vs.new AtomicLongThread()).start();
}
long endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
(vs.new LongAdderThread()).start();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
}
}
I got something like the following as the standard output every time I run this program:
AtomicLong--Number: 100000000, Time: 2330
LongAdder--Number: 99882179, Time: 469
Apparently I've got a wrong value with LongAdder, but I can not figure out where I did wrong.
Can you help me?
updated
Under the help of everybody here and #Ravindra Ranwala, I updated my answer for the exercise above:
import java.io.*;
import java.util.*;
import java.nio.file.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class AtomicLongVsLongAddr {
// 9. Generate 1,000 threads, each of which increments a counter
// 100,000 times. Compare the performance of using AtomicLong
// versus LongAdder.
AtomicLong al = new AtomicLong(0);
LongAdder la = new LongAdder();
public class AtomicLongThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 100000; i ++) {
al.incrementAndGet();
}
}
}
public class LongAdderThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 100000; i ++) {
la.increment();
}
}
}
public static void main(String[] args) {
try{
long startTime;
long endTime;
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
Thread[] t = new Thread[1000];
for (int i = 0; i < 1000; i ++) {
t[i] = vs.new AtomicLongThread();
}
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
t[i].start();
t[i].join();
}
endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
for (int i = 0; i < 1000; i ++) {
t[i] = vs.new LongAdderThread();
}
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
t[i].start();
t[i].join();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
If there still are any wrong, please point it out for me. Thanks everyone.
Call Thread.join on all the threads and wait till all of them are completed. It seems your main thread exits before other threads that increment the two variables completed. What you are getting here is some intermediary result.
Here's the code,
public static void main(String[] args) throws InterruptedException {
final List<Thread> adderThreads = new ArrayList<>();
final List<Thread> atomicThreads = new ArrayList<>();
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
final AtomicLongThread atomicThread = vs.new AtomicLongThread();
atomicThreads.add(atomicThread);
atomicThread.start();
}
for (Thread thread : atomicThreads) {
thread.join();
}
long endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
final LongAdderThread adderThread = vs.new LongAdderThread();
adderThreads.add(adderThread);
adderThread.start();
}
for (Thread thread : adderThreads) {
thread.join();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
}
Your code isn't synchronous - The main thread will exit/proceed before it's finished with the counter threads, thus creating the difference.

Simple program needs 3x more time in C#

I have written a simple "benchmark" to compare performances in same cases - in Java and C#. In Java the program needs about 2,2s to complete (ran multiple times), in C# it needs 7,4s (ran multiple times).
Software used: Windows, Java (JDK 10), C# (.NET Framework 4.6.1)
Isn't CSharp's runtime jitting, or why is Java that times faster?
The program in Java:
Dummy[] dummies = new Dummy[100000000]; // Dummy = empty class
var timer = new Timer();
timer.start();
for (int i = 0; i < 100000000; i++) {
dummies[i] = new Dummy();
}
timer.stop();
System.out.println(String.format("Elapsed time: %sms", timer.millis(2)));
And in C#:
Dummy[] dummies = new Dummy[100000000]; // Dummy = empty class
var timer = new Timer();
timer.Start();
for (int i = 0; i < 100000000; i++)
{
dummies[i] = new Dummy();
}
timer.Stop();
Console.WriteLine("Elapsed time: {0}ms", timer.Millis(2));
The Timer class in Java:
public class Timer {
private long startTime, stopTime;
public void start() {
startTime = System.nanoTime();
stopTime = startTime;
}
public void stop() {
stopTime = System.nanoTime();
}
public double millis() {
return stopTime / 1e6 - startTime / 1e6;
}
public double millis(int decimals) {
double factor = Math.pow(10.0, decimals);
return Math.round(millis() * factor) / factor;
}
}
And in C#:
public class Timer
{
private double startTime, stopTime;
public void start()
{
startTime = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds;
stopTime = startTime;
}
public void stop()
{
stopTime = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds;
}
public double Millis()
{
return stopTime - startTime;
}
public double Millis(int decimals)
{
return Math.Round(Millis(), decimals);
}
}

Stopwatch Class

public class Stopwatch {
private double startTime;
private double endTime;
public static void main(String[]args) {
}
public void stopWatch() {
startTime = System.currentTimeMillis();
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
endTime = System.currentTimeMillis();
}
public long getStartTime()
{
return (long) startTime;
}
public long getEndTime()
{
return (long) endTime;
}
public long getElapsedTime()
{
return (long) (System.currentTimeMillis() - startTime);
}
public short getMilliSeconds()
{
return (short)((System.currentTimeMillis() - startTime) % 1000);
}
}
I need to run this testSearch with the StopWatch Class above
When I input the array size I get the Linear Search result but the Binary Search stays at 0 nano seconds
import java.util.*;
public class testSearch {
public static void main(String[] args){
// input array size from user
Scanner input = new Scanner(System.in);
System.out.print("Enter array size: ");
int size = input.nextInt();
System.out.println();
// create the array (the numbers do not really matter)
int[] numbers = new int[size];
for(int i=0; i<numbers.length; i++){
// we want the numbers sorted for binary search
// so why not just the numbers 0,1,...,size-1
numbers[i]=i;
}
// store the time now
long startTime = System.nanoTime();
// linear search for size (which is not in the array)
linearSearch(numbers,size);
// display the time elapsed
System.out.println("The time taken by Linear Search is " + (System.nanoTime() - startTime) + "nanoseconds.");
// prepare to measure the time elapsed again
startTime = System.nanoTime();
// binary search for size
binarySearch(numbers,size);
// display the time elapsed
System.out.println("The time taken by Binary Search is " + (System.nanoTime() - startTime) + "nanoseconds.");
}
public static boolean linearSearch(int[] a, int key) {
for(int i=0; i<a.length; i++){
if(a[i]==key) return true;
}
return false;
}
public static boolean binarySearch(int[] a, int key) {
int low = 0;
int high = a.length -1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (a[mid]>key) {
high = mid - 1;
} else if (a[mid]<key) {
low = mid + 1;
} else {
return true;
}
}
return false;
}
}
Here is the output that I get
Enter array size:
2
The time taken by Linear Search is 1456959922854 milliseconds.
The time taken by Binary Search is 0 milliseconds.

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.

Categories