I am writing a multi-threaded Java program that generates lot of random numbers.
Additional Details:
These numbers are used to create a list of random numbers from 0-99 without repetition and such that every number in the range 0-99 exists in the list (In other words, the list contains 100 unique elements in the range 0-99).
Generating Random Numbers [Things already tried!]
- I have an ArrayList of numbers from 0-100. I generate a random number and use it as an index which is used to pop out an element from the
ArrayList. - I have used
Collections.shuffle().
Here is the code for approach 1:
ArrayList<Integer> arr = new ArrayList<Integer>();
for (int i = 0; i < N; i++){
arr.add(i, i);
}
for(int i=0; i<N; i++){
int indx = rand.nextInt(arr.size());
res.add(arr.get(indx));
arr.remove(indx);
}
For second approach, I replaced the second for loop with Collections.shuffle(arr).
As generating list of random numbers is the most expensive part of my algorithm, I want to optimize it. This brings me to the questions:
- What is the fastest way to generate random numbers?
- What is the fastest way to generate the list of random numbers as described above?
PS:
- I found
Collections.shuffle()to be slower than the first approach - Someone suggested me using
rngdto generate random numbers from hardware in Unix. Has anyone tried this before? How do you do that?
I think the problem with
Collections.shuffle()is that is uses defaultRandominstance which is a thread-safe singleton. You say that your program is multi-threaded, so I can imagine synchronization inRandombeing a bottle-neck.If you are happily running on Java 7, simply use
ThreadLocalRandom. Look carefully, there is a version ofshuffle()takingRandominstance explicitly:where
threadLocalRandomis created only once.On Java 6 you can simply create a single instance of
Randomonce per thread. Note that you shouldn’t create a new instance ofRandomper run, unless you can provide random seed every time.