Reputation: 1443
I'm making a sort of probability simulator that will run for either a certain amount of time, or for a certain amount of repetitions. I'm looking to optimize it, and it's currently multi-threaded with each ProbabilityWorker
extending Thread
, and the main program will automatically allocate n
threads, where n
is however many threads are available (example: on my Core i3-7100U, this is 4).
I'm analyzing the performance of this, and I'm realizing that the methodology I'm using to get the current time with respect to the end time is causing a lot of overhead.
For the mode where it can "run for a certain amount of time," I was making new Date
objects as a part of the loop condition, then I changed it to a faster System.currentTimeMillis()
to try and save time, but I'm noticing even that induces overhead.
My run
function looks like this:
public void run() {
if (mode) {
while (completed < repitions) {
resultSet[randy.nextInt(o)]++;
completed++;
}
} else {
while (System.currentTimeMillis() < endTime) {
resultSet[randy.nextInt(o)]++;
completed++;
}
}
done = true;
}
Where mode
is true
if running for an amount of repetitions, randy
is a Random, o
is the amount of possible outcomes, and endTime
is the end point in milliseconds, system time (which could be modified, program takes in an amount of seconds, and endTime
is calculated by the current time plus secondsInput * 1000
).
In addition, on the same Core i3-7100U, these are my performance statistics:
DE-WEY-LAPTOP:/mnt/c/Users/danny/Documents/Programming/Data Structures/Probability$ java Main -n 10000000000
Running 10000000000 repitions of the probability simulator with 2 possible outcomes.
4 threads detected on system; doing 2500000000 repitions per thread.
Done. Gathering results from worker threads...
Done. Printing results...
Outcome 1: 4999997330 out of 10000000000 (49.9999733%)
Outcome 2: 5000002670 out of 10000000000 (50.0000267%)
Time taken: 43.443 seconds (2.301866813986143E8 ops/sec)
DE-WEY-LAPTOP:/mnt/c/Users/danny/Documents/Programming/Data Structures/Probability$ java Main -t 44
Running the probability simulator for 44 seconds using 4 threads.
Done. Gathering results from worker threads...
Done. Printing results...
Outcome 1: 141568074 out of 283130850 (50.000935609807264%)
Outcome 2: 141562776 out of 283130850 (49.999064390192736%)
Time taken: 44 seconds (6434792.045454546 ops/sec)
My question is, is there a way to optimize the System.currentTimeMillis()
call to either not have it or reduce how much time it takes? Is there another faster call I can use?
Upvotes: 5
Views: 1467
Reputation: 121078
You should really be looking into System.nanoTime
(and stick to that) - that is the best you can get in the JVM AFAIK. Besides the fact that it measures elapsed time without any notion of clock time, it is the fastest too - that is the reason JMH uses it (or any other sane micro-benchmark I hope).
Besides the fact that System.currentTimeMillis
returns ms
precision (and there are things that are done faster than 1ms
), the difference between two calls to this method can return a negative value.
There are two things to keep in mind though, first is that each call to System.nanoTime
has a performance implication as well, on average it takes (on my, close to your CPU and JVM-9) 25 ns
per call.
The last point is that System.nanoTime
has nano-second precision, but not nano-second accuracy. This means that when you call:
long start = System.nanoTime();
long end = System.nanoTime();
both of the results will return a number that has nano-second precision, that is they will have multiple digits.
But that number can not be very accurate. Well, accurate according to what you might ask. Since System.nanoTime
returns a value that is arbitrary, there isn't something to compare it with, unless other call to System.nanoTime
, thus:
long result = end - start;
is/might not going to be a nano-second accurate result. The inaccuracy of this is around 1 micro-second, on my laptop is around 0.2-0.5 micro-seconds.
Use System.nanoTime
, there isn't something faster or more fine-grained.
Upvotes: 3