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.
Related
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
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
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 write an OpenGL app in Java using JOGL. I am trying to completely avoid the creation of objects during the main app's phase as it could lead to the small periodic lag caused by GC.
I want to wrap some JOGL's methods with my own. Imagine a method void method(int[] result, int offset) which receives the pointer to an array and an offset and puts one integer value into it at the specified index. I want to wrap it with simple int getResult()
So I need to create a temporary array somewhere and I must do that in advance (according to 1).
But if it will be stored in a field of the class containing this wrapper method, this will force me to make the wrapper method synchronized. I know that sychronization in time of mostly single-thread access shouldn't produce a big overhead but I still want to know is it there a better solution for this.
Notes:
Synchronized is not the answer, 3.000.000 of empty synchronized blocks, just monitorenter-monitorexit take 17 ms. You have only 16.(6) if you want to keep 60 fps.
As I haven't enough power for voting up the only way I found to appreciate Dave's answer is writting a demo:
class Test {
private static final int CYCLES = 1000000000;
int[] global = new int[1];
ThreadLocal<int[]> local = new ThreadLocal<int[]>();
void _fastButIncorrect() { global[0] = 1; }
synchronized void _slowButCorrect() { global[0] = 1; }
void _amazing() {
int[] tmp = local.get();
if( tmp == null ){
tmp = new int[1];
local.set(tmp);
}
tmp[0] = 1;
}
long fastButIncorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _fastButIncorrect();
return System.currentTimeMillis() - l;
}
long slowButCorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _slowButCorrect();
return System.currentTimeMillis() - l;
}
long amazing() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _amazing();
return System.currentTimeMillis() - l;
}
void test() {
System.out.println(
"fastButIncorrect cold: " + fastButIncorrect() + "\n" +
"slowButCorrect cold: " + slowButCorrect() + "\n" +
"amazing cold: " + amazing() + "\n" +
"fastButIncorrect hot: " + fastButIncorrect() + "\n" +
"slowButCorrect hot: " + slowButCorrect() + "\n" +
"amazing hot: " + amazing() + "\n"
);
}
public static void main(String[] args) {
new Test().test();
}
}
on my machine the results are:
fastButIncorrect cold: 40
slowButCorrect cold: 8871
amazing cold: 46
fastButIncorrect hot: 38
slowButCorrect hot: 9165
amazing hot: 41
Thanks again, Dave!
If you don't have too many threads, you can use a ThreadLocal:
ThreadLocal<int[]> tmpArrayThreadLocal = new ThreadLocal<int[]>();
code to use this:
int[] tmpArray = tmpArrayThreadLocal.get();
if( tmpArray == null ){
tmpArray = new int[100];
tmpArrayThreadLocal.set(tmpArray);
}
method(tmpArray, 5)
You could clean up the code by encapsulating the ThreadLocal in another class.
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 ;
}