This question already has answers here:
How do I write a correct micro-benchmark in Java?
(11 answers)
Closed 4 years ago.
please i need help i am writing this code to be able to display my execution time anytime i run a program but i usually get different time even when its the same input
after importing all this
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/** Class KnuthMorrisPratt **/
public class Knuth1
{
/** Failure array **/
private int[] failure;
/** Constructor **/
public Knuth1(String text, String pat)
{
/** pre construct failure array for a pattern **/
failure = new int[pat.length()];
fail(pat);
/** find match **/
int pos = posMatch(text, pat);
if (pos == -1)
System.out.println("\nNo match found");
else
System.out.println("\nMatch found at index "+ pos);
}
/** Failure function for a pattern **/
private void fail(String pat)
{
int n = pat.length();
failure[0] = -1;
for (int j = 1; j < n; j++)
{
int i = failure[j - 1];
while ((pat.charAt(j) != pat.charAt(i + 1)) && i >= 0)
i = failure[i];
if (pat.charAt(j) == pat.charAt(i + 1))
failure[j] = i + 1;
else
failure[j] = -1;
}
}
/** Function to find match for a pattern **/
private int posMatch(String text, String pat)
{
int i = 0, j = 0;
int lens = text.length();
int lenp = pat.length();
while (i < lens && j < lenp)
{
if (text.charAt(i) == pat.charAt(j))
{
i++;
j++;
}
else if (j == 0)
i++;
else
j = failure[j - 1] + 1;
}
return ((j == lenp) ? (i - lenp) : -1);
}
/** Main Function **/
public static void main(String[] args) throws IOException
{
//i think its here were i get the input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in) ));
System.out.println("Knuth Morris Pratt Test\n");
System.out.println("\nEnter Text: ");
String text = br.readLine();
System.out.print("\nEnter Pattern");
String pattern = br.readLine();
double starttime = System.nanoTime();
Knuth1 kmp = new Knuth1(text, pattern);
double endtime = System.nanoTime();
double executiontime = (endtime - starttime )/1000000000;
// System.out.printf("%.4f","Execution Time = "+ executiontime + " Seconds");
System.out.print("Execution Time = ");
System.out.format("%.4f", executiontime);
System.out.print(" Seconds");
// System.out.println(starttime);
// System.out.println(endtime);
//I love programming with JAVA and Php. It’s fun and interesting.
}
}
this code will check an input strings and pick out the unique word and the try to also display the execution time for the program... what i really want now is to make sure the execution time remain the same when i input the same input.
If you don't care about reusing the timed functionality, use System.nanoTime()
long before;
long after;
// Get time before
before = System.nanoTime();
// Code you want to execute here
// Get time after
after = System.nanoTime();
// Calculate duration
long diff = after - before;
You can encapsulate any code you want into a Runnable or using any of Java 8's new Predicate or Function interfaces which are very similar. You can put the code that you want to run in a lambda expression (like an anonymous function) and pass it to a static method that calculates in nanoseconds the amount of time it takes the runnable object to execute.
This is more code than what is necessary, but it reusable in that you don't have to keep writing start = System.currentTimeMillis() or System.nanoTime()and doing arithmetic every time you want to time something. You can put this function in your static library and use it whenever you want.
/**
* Times a runnable. Note, there
* is probably overhead associated with
* creating a Runnable object, but if
* assume that's constant for all Runnable
* objects, then we can simply ignore it
*
* #param runnable Runnable to run
* #return Number of nanoseconds it took to run the Runnable
*/
public static long timedAction(Runnable runnable) {
long before;
long after;
before = System.nanoTime();
runnable.run();
after = System.nanoTime();
return after - before;
}
This is how I use this code block:
public static void main(String[] args) throws Exception {
final int numKeys = 1000000;
// Builds an AVL tree
Runnable snippet = () -> {
Tree<Integer, Object> avl = new AVLTree<>();
for (int i = 0; i < numKeys; i++) {
avl.insert(i, i);
}
};
long nanoSecond = Util.timedAction(snippet);
double seconds = Mathematics.nanosecondsToSeconds(nanoSecond);
System.out.println(seconds);
}
Output:
0.493316448
Related
I have a piece of the source code in java8:
public class Test {
public static void main(String[] args) {
testObject(1.3);
testObject(1.4);
}
private static void testObject(double num) {
System.out.println("test:" + num);
long sta = System.currentTimeMillis();
int size = 10000000;
Object[] o = new Object[(int) (size * num)];
for (int i = 0; i < size; i++) {
o[i] = "" + i;
}
System.out.println("object[]: " + (System.currentTimeMillis() - sta) + " ms");
}
}
execution Result:
test:1.3
object[]: 7694 ms
test:1.4
object[]: 3826 ms
Why is the running time so different when my quantity is 1.4 * size?
I wanted to see how Java array assignment works, but I couldn't find anything on google.
In addition you have to keep in mind that System.currentTimeMillis returns a "Wall-Clock-Time". If your OS does a reschedule during the for-loop and a different process gets the cpu, the Wall-Clock-Time increases but your program won't execute.
I'm doing a Java programming assignment which involves bubble sorting a .dat file BetelgeuseNames.dat with strings in it alphabetically. My AP Computer Science A teacher told me my code is correct, but it still gives the wrong output.
There are three classes called BubbleSort, BubbleSortTimer, and StopWatch. The program runs from BubbleSortTimer.
BubbleSort:
import java.util.ArrayList;
import javax.swing.JOptionPane;
import java.io.FileWriter;
import java.io.IOException;
public class BubbleSort {
// Private instance variables:
private ArrayList<String> list;
private int number;
public BubbleSort(ArrayList<String> a_list) {
list = a_list;
}
public void swap(int first, int second) {
String temp1 = list.get(first);
String temp2 = list.get(second);
list.set(first, temp2);
list.set(second, temp1);
}
public int getNumber() {
String numStr;
numStr = JOptionPane.showInputDialog("How many names do you want to sort?");
number = Integer.parseInt(numStr);
return number;
}
public void printSorted() {
try {
FileWriter writer = new FileWriter("sorted.dat");
for (int i = 0; i < number; i++) {
writer.write(list.get(i) + "\n");
}
writer.close();
} catch (IOException exception) {
System.out.println("Error processing file: " + exception);
}
}
public void bubbleSort() {
for (int i = 0; i < number; i++) {
for (int j = 0; j < number - i - 1; j++) {
if (list.get(i).compareTo(list.get(i+1)) > 0) {
swap(i, i + 1);
}
}
}
} // End method
}
BubbleSortTimer:
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.FileReader;
import javax.swing.JOptionPane;
import java.io.IOException;
public class BubbleSortTimer {
private ArrayList<String> list = new ArrayList<String>();
public void readNames() {
try {
FileReader reader = new FileReader("BetelgeuseNames.dat");
BufferedReader in = new BufferedReader(reader);
boolean done = false;
String name;
while (done == false) {
name = in.readLine();
if (name == null) {
done = true;
} else {
list.add(name);
}
}
reader.close();
} catch (IOException exception) {
System.out.println("Error processing file: " + exception);
}
} // End method
public void runSort() {
readNames();
StopWatch timer = new StopWatch();
BubbleSort sorter = new BubbleSort(list);
int number = sorter.getNumber();
timer.start();
sorter.bubbleSort();
timer.stop();
sorter.printSorted();
String msg = "Number of names sorted: " + number + "\nMilliseconds required to sort: " + timer.getElapsedTime() + "\nOutput file is \"sorted.dat\"";
JOptionPane.showMessageDialog(null, msg);
}
public static void main(String[] args) {
BubbleSortTimer bubble = new BubbleSortTimer();
bubble.runSort();
}
}
StopWatch:
/**
* A stopwatch accumulates time when it is running. You can
* repeatedly start and stop the stopwatch. You can use a
* stopwatch to measure the running time of a program.
* from section 18.2 of Horstmann's CCJ
*/
public class StopWatch {
/**
* Constructs a stopwatch that is in the stopped state
* and has no time accumulated.
*/
public StopWatch() {
reset();
}
/**
* Starts the stopwatch. Times starts accumulating now.
*/
public void start() {
if (isRunning) return;
isRunning = true;
startTime = System.currentTimeMillis();
}
/**
* Stops the stopwatch. Time stops accumulating and is
* added to the elapsed time.
*/
public void stop() {
if (!isRunning) return;
isRunning = false;
long endTime = System.currentTimeMillis();
elapsedTime = elapsedTime + endTime - startTime;
}
/**
* Returns the total elapsed time.
#return the total elapsed time
*/
public long getElapsedTime() {
if (isRunning) {
long endTime = System.currentTimeMillis();
elapsedTime = elapsedTime + endTime - startTime;
startTime = endTime;
}
return elapsedTime;
}
/**
* Stops the watch and resets the elapsed time to 0.
*/
public void reset() {
elapsedTime = 0;
isRunning = false;
}
private long elapsedTime;
private long startTime;
private boolean isRunning;
}
Input:
Moewm
Bmlzvltcso
Aqxjor
Wwgjie
Qqqtpivd
Xgyhaerv
Wqpjwdvxjq
Ecsfnow
Zlptuqxctt
Jhtprwvopk
Expected Output:
Aqxjor
Bmlzvltcso
Ecsfnow
Jhtprwvopk
Moewm
Qqqtpivd
Wqpjwdvxjq
Wwgjie
Xgyhaerv
Zlptuqxctt
Actual Output:
Bmlzvltcso
Aqxjor
Moewm
Qqqtpivd
Wwgjie
Wqpjwdvxjq
Ecsfnow
Xgyhaerv
Jhtprwvopk
Zlptuqxctt
This is how Android did (binary) sorting (edited to fix this situation):
public void binarySort() {
int lo = 0; // sort start
for (int start=lo ; start < number; start++) {
String pivot = list.get(start);
// Set left (and right) to the index where list.get(start) (pivot) belongs
int left = 0;
int right = start;
assert left <= right;
/*
* Invariants:
* pivot >= all in [lo, left].
* pivot < all in [right, start].
*/
while (left < right) {
int mid = (left + right) >>> 1;
if (pivot.compareTo(list.get(mid)) < 0)
right = mid;
else
left = mid + 1;
}
assert left == right;
/*
* The invariants still hold: pivot >= all in [lo, left] and
* pivot < all in [left, start], so pivot belongs at left. Note
* that if there are elements equal to pivot, left points to the
* first slot after them -- that's why this sort is stable.
* Slide elements over to make room for pivot.
*/
int n = start - left; // The number of elements to move
// Switch is just reshifter in default case
switch (n) {
case 2: list.set(left + 2,list.get(left + 1));
case 1: list.set(left + 1,list.get(left));
break;
default:
if(n>0){
list.add(left,list.remove(left+n));
}
}
list.set(left,pivot);
}
}
This is how you can do (bubble) sorting:
public void bubbleSort() {
for (int i = 0; i < number; i++) {
for (int j = i + 1; j < number; j++) {
if (list.get(i).compareTo(list.get(j)) > 0) {
swap(i, j);
}
}
}
}
BUBBLE SORTING V/S BINARY SORTING:
OFF TOPIC: As you can compare above, bubble sorting is easier to code/read/understand and is also faster as compared to binary sorting, because binary sorting (actually) uses array recreation many times which ofcourse takes more time compared to swap.
Because there is a problem with your bubbleSort() method. Please try this way.
public void bubbleSort() {
for (int i = 0; i < number; i++) {
for (int j = 1; j < number - i; j++) {
if (list.get(j - 1).compareTo(list.get(j)) > 0) {
swap(j - 1, j);
}
}
}
}
Have an issue where the performance of a simple loop (see code below in LoopTest.performTest) varies dramatically, but is consistent for the lifetime of the process.
For example, when run from within Weblogic/Tomcat it may achieve an average of 3.5 billion iterations per second. Re-start and it may only achieve 20 million iterations per second. This will remain consistent for the lifetime of the process. When it has been run directly from the command line, on every occasion, it has run fast.
This has been run under linux, windows, Tomcat & WebLogic. The slow execution occurs more regularly in WebLogic than Tomcat.
Test Specifics
The test code moves any potential OS calls (timing) to before and after the test, with differing size loops which should allow any slow OS calls to be apparent as a progressive apparent performance improvement as loop size increases.
The number of iterations performed by the test is determined by time (see runTest) rather than being fixed due to large variation in performance and is thus more complex than may initially be expected.
public static abstract class PerformanceTest {
private final String name;
public PerformanceTest(String name) {
this.name = name;
}
/**
* Return value to ensure loops etc not optimised away.
*
* #param loopCount
* #return
*/
public abstract long performTest(final long loopCount);
public String getName() {
return name;
}
}
private static class LoopTest extends PerformanceTest {
LoopTest() {
super("Loop");
}
#Override
public long performTest(final long loopCount) {
long sum=0;
for(long i=0;i<loopCount;i++) {
sum+=i;
}
return sum;
}
}
public static List<PerformanceTest> loadTests() {
List<PerformanceTest> performanceTests = new ArrayList<PerformanceTest>();
performanceTests.add(new LoopTest());
return performanceTests;
}
public static void main(String[] argv) {
int maxDuration = 30;
if (argv.length == 1) {
maxDuration = Integer.parseInt(argv[0]);
}
List<PerformanceTest> tests = loadTests();
for(PerformanceTest test : tests) {
runTest(test, maxDuration);
}
}
public static void runTest(PerformanceTest test, int maxDuration) {
System.out.println("Processing " + test.getName());
long stopDuration = 1000 * maxDuration;
long estimatedDuration = 1;
long priorDelta = 1;
long loopCount=10;
while (estimatedDuration < stopDuration) {
long startTime = System.currentTimeMillis();
test.performTest(loopCount);
long endTime = System.currentTimeMillis();
long delta = endTime - startTime;
estimatedDuration = delta * Math.max(10, delta / Math.min(estimatedDuration, priorDelta));
if (estimatedDuration <= 0) {
estimatedDuration = 1;
}
priorDelta = delta;
if (priorDelta <= 0) {
priorDelta = 1;
}
if (delta > 0) {
double itemsPerSecond = 1000 * (double)loopCount / (double)delta;
DecimalFormat formatter;
if (itemsPerSecond < 1) {
formatter = new DecimalFormat( "#,###,###,##0.000");
} else if (itemsPerSecond < 10) {
formatter = new DecimalFormat( "#,###,###,##0.0");
} else {
formatter = new DecimalFormat( "#,###,###,##0");
}
System.out.println(" " + loopCount + " : Duration " + delta + ", Items Per-Second: " + formatter.format(itemsPerSecond));
}
loopCount*=10;
}
}
I have written a java program, and I want to see when it runs how much RAM it uses. Is there any way to see how much RAM usage is related to my program? I mean something like time usage of the program that can be seen by writing this code before and after calling the main code:
long startTime = System.currentTimeMillis();
new Main();
long endTime = System.currentTimeMillis();
System.out.println("Total Time: " + (endTime - startTime));
You can use the following class. Implemeting the Instantiator interface you can execute several time the same process to get a precise view of the memory consumption
public class SizeOfUtil {
private static final Runtime runtime = Runtime.getRuntime();
private static final int OBJECT_COUNT = 100000;
/**
* Return the size of an object instantiated using the instantiator
*
* #param instantiator
* #return byte size of the instantiate object
*/
static public int execute(Instantiator instantiator) {
runGarbageCollection();
usedMemory();
Object[] objects = new Object[OBJECT_COUNT + 1];
long heapSize = 0;
for (int i = 0; i < OBJECT_COUNT + 1; ++i) {
Object object = instantiator.execute();
if (i > 0)
objects[i] = object;
else {
object = null;
runGarbageCollection();
heapSize = usedMemory();
}
}
runGarbageCollection();
long heap2 = usedMemory(); // Take an after heap snapshot:
final int size = Math.round(((float) (heap2 - heapSize)) / OBJECT_COUNT);
for (int i = 1; i < OBJECT_COUNT + 1; ++i)
objects[i] = null;
objects = null;
return size;
}
private static void runGarbageCollection() {
for (int r = 0; r < 4; ++r){
long usedMem1 = usedMemory();
long usedMem2 = Long.MAX_VALUE;
for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) {
runtime.runFinalization();
runtime.gc();
Thread.yield();
usedMem2 = usedMem1;
usedMem1 = usedMemory();
}
}
}
private static long usedMemory() {
return runtime.totalMemory() - runtime.freeMemory();
}
}
Implement the interface
public interface Instantiator { Object execute(); }
With the code you want to test
public void sizeOfInteger(){
int size = SizeOfUtil.execute(new Instantiator(){
#Override public Object execute() {
return new Integer (3);
}
});
System.out.println(Integer.class.getSimpleName() + " size = " + size + " bytes");
}
source : Java Tutorial Java Size of objects
I think this must help:
visualvm
it comes with jdk, and have many thing that help to control memory usage
you can get a very close value by comparing the free memory of the JVM before and after the loading of your program. The difference is very close to the memory usage of your program. To get the JVM free memory use
Runtime.getRuntime().freeMemory()
To get the memory usage do this:
public static void main (String args[]){
long initial = Runtime.getRuntime().freeMemory(); //this must be the first line of code executed
//run your program ... load gui etc
long memoryUsage = Runtime.getRuntime().freeMemory() - initial ;
}
I am trying to understand the utilities in java.util.concurrent package and learnt that we can submit callable objects to the ExecutorService, which returns Future, which is filled with the value returned by the callable, after successful completion of task within call() method.
I am understanding that all the callables are executed concurrently using multiple threads.
When I wanted to see how much improvement ExecutorService gives over the batch task execution, i thought of capturing time.
Following is the code which i tried to execute -
package concurrency;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExecutorExample {
private static Callable<String> callable = new Callable<String>() {
#Override
public String call() throws Exception {
StringBuilder builder = new StringBuilder();
for(int i=0; i<5; i++) {
builder.append(i);
}
return builder.toString();
}
};
public static void main(String [] args) {
long start = System.currentTimeMillis();
ExecutorService service = Executors.newFixedThreadPool(5);
List<Future<String>> futures = new ArrayList<Future<String>>();
for(int i=0; i<5; i++) {
Future<String> value = service.submit(callable);
futures.add(value);
}
for(Future<String> f : futures) {
try {
System.out.println(f.isDone() + " " + f.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("Executer callable time - " + (end - start));
service.shutdown();
start = System.currentTimeMillis();
for(int i=0; i<5; i++) {
StringBuilder builder = new StringBuilder();
for(int j=0; j<5; j++) {
builder.append(j);
}
System.out.println(builder.toString());
}
end = System.currentTimeMillis();
System.out.println("Normal time - " + (end - start));
}
}
and here is the output of this -
true 01234
true 01234
true 01234
true 01234
true 01234
Executer callable time - 5
01234
01234
01234
01234
01234
Normal time - 0
Please let me know if I am missing something OR understanding something in a wrong way.
Thanks in advance for your time and help for this thread.
If you task in Callable is to small, you won't get benefits from concurrency due task switching and overhead for initialisation. Try to add more heavier loop in callable, say 1000000 iterations, and you can see difference
When you run any code esp for the first time, it takes time. If you pass a task to another thread it can take 1-10 micro-seconds and if your task take less time than this, the overhead can be greater than the benefit. i.e. using multiple threads can be much slower than using a single thread if your overhead is high enough.
I suggest you
increase the cost of the task to 1000 iterations.
make sure the result is not discarded in the single threaded example
run both tests for at least a couple of seconds to ensure the code has warmed up.
Not an answer (but I am not sure the code will fit a comment). To expand a bit on what Peter said, there is usually a sweet spot for the size of your jobs (measured in execution time), to balance pool/queue overhead with fair work distribution among workers. The code example helps find an estimate for that sweet spot. Run on your target hardware.
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class FibonacciFork extends RecursiveTask<Long> {
private static final long serialVersionUID = 1L;
public FibonacciFork( long n) {
super();
this.n = n;
}
static ForkJoinPool fjp = new ForkJoinPool( Runtime.getRuntime().availableProcessors());
static long fibonacci0( long n) {
if ( n < 2) {
return n;
}
return fibonacci0( n - 1) + fibonacci0( n - 2);
}
static int rekLimit = 8;
private static long stealCount;
long n;
private long forkCount;
private static AtomicLong forks = new AtomicLong( 0);
public static void main( String[] args) {
int n = 45;
long times[] = getSingleThreadNanos( n);
System.out.println( "Single Thread Times complete");
for ( int r = 2; r <= n; r++) {
runWithRecursionLimit( r, n, times[ r]);
}
}
private static long[] getSingleThreadNanos( int n) {
final long times[] = new long[ n + 1];
ExecutorService es = Executors.newFixedThreadPool( Math.max( 1, Runtime.getRuntime().availableProcessors() / 2));
for ( int i = 2; i <= n; i++) {
final int arg = i;
Runnable runner = new Runnable() {
#Override
public void run() {
long start = System.nanoTime();
final int minRuntime = 1000000000;
long runUntil = start + minRuntime;
long result = fibonacci0( arg);
long end = System.nanoTime();
int ntimes = Math.max( 1, ( int) ( minRuntime / ( end - start)));
if ( ntimes > 1) {
start = System.nanoTime();
for ( int i = 0; i < ntimes; i++) {
result = fibonacci0( arg);
}
end = System.nanoTime();
}
times[ arg] = ( end - start) / ntimes;
}
};
es.execute( runner);
}
es.shutdown();
try {
es.awaitTermination( 1, TimeUnit.HOURS);
} catch ( InterruptedException e) {
System.out.println( "Single Timeout");
}
return times;
}
private static void runWithRecursionLimit( int r, int arg, long singleThreadNanos) {
rekLimit = r;
long start = System.currentTimeMillis();
long result = fibonacci( arg);
long end = System.currentTimeMillis();
// Steals zählen
long currentSteals = fjp.getStealCount();
long newSteals = currentSteals - stealCount;
stealCount = currentSteals;
long forksCount = forks.getAndSet( 0);
System.out.println( "Fib(" + arg + ")=" + result + " in " + ( end-start) + "ms, recursion limit: " + r +
" at " + ( singleThreadNanos / 1e6) + "ms, steals: " + newSteals + " forks " + forksCount);
}
static long fibonacci( final long arg) {
FibonacciFork task = new FibonacciFork( arg);
long result = fjp.invoke( task);
forks.set( task.forkCount);
return result;
}
#Override
protected Long compute() {
if ( n <= rekLimit) {
return fibonacci0( n);
}
FibonacciFork ff1 = new FibonacciFork( n-1);
FibonacciFork ff2 = new FibonacciFork( n-2);
ff1.fork();
long r2 = ff2.compute();
long r1 = ff1.join();
forkCount = ff2.forkCount + ff1.forkCount + 1;
return r1 + r2;
}
}