Let me clarify that the method described below is workable. I hope to improve the throughput of the method. It works, and it works quite well. We strive to increase throughput even further, which is why I am studying this.
The challenge is to improve the performance of the scoring algorithm, which returns the best result for a set of tasks. I have a set of tasks that I perform to evaluate with ExecutorService. Each task checks to see if it currently has the best score, and updates the best score in a synchronized fashion if it is new. To give some insight into the scale at which I work, each task takes a fraction of a millisecond, but there are thousands of them, leaving several hundred milliseconds to find the best. I execute this counting algorithm several hundred times per minute. The result is that 30 seconds out of 60 are spent executing this estimation algorithm.
When my thread pool has 8 threads (with 24 virtual cores), tasks take 0.3 ms each. When I have 20 threads (the same machine, 24 virtual cores), the tasks take 0.6 ms each. I suspect that when I add more threads to my thread pool ExecutorService, that my performance degrades due to this synchronization for a better result (more threads fighting for blocking).
I searched quite a lot, but I can not find satisfactory (in fact, I can not find any alternatives). I am going to collect all the grades and either save them in sorted order or sort them after completing all the tasks, but I'm not sure if this will be any improvement.
Does anyone have any thoughts on another, more efficient way to collect better scores?
Here's the current methodology:
final double[] bestScore = { Double.MAX_VALUE };
tasks.add(Executors.callable(new Runnable() {
public void run() {
double score =
if (score < bestScore[0]) {
synchronized(bestScore) {
if (score < bestScore[0]) {
bestScore[0] = score;
...
}
}
}
}
}
}
List<Future<Object>> futures = executorService.invokeAll(tasks );
...