vendredi 19 janvier 2018

Timestamp with Random Number in JS

This is a follow-up question to the one I asked previously, Is this JS Unique ID Generator Unreliable? (Getting collisions).

In the scriptlet below I'm generating 10000 random numbers using 2 methods. Method 1 is a straight random number up to 10^6, while Method 2 concatenates that random number up to 10^6 (same idea as in [1]) with the current JS Date().time() timestamp.

My question is, if you keep clicking the test button, you see that [1] always produces 10000 unique numbers but [2] produces ~9500 no matter what. Why is that? The chances of getting a +/-1 from a previous random number in [0..10^6] and having that mixed with the timestamp of exactly the opposite +/-1 for the timestamp concatenation are impossible. We are generating pretty much on the same millisecond in a loop. 10^6 is a huge limit, much bigger than in my original question, and we know that's true because Method [1] works perfectly.

Is there truncation of some kind of going on, which trims the string and makes it more likely to get duplicates? Paradoxically, a smaller string works better than a larger string using the same RNG inside it. But if there's no truncation, I would expect results to be 100% as in [1].

function run() {
var nums1 = new Set(), nums2 = new Set()

for (var i = 0; i < 10000; i++) {
   nums1.add(random10to6th());
}
for (var i = 0; i < 10000; i++) {
   nums2.add(random10to6th_concatToTimestamp());
}
console.clear();
console.log('Random 10^6 Unique set: ' + nums1.size);
console.log('Random 10^6 and Concat to Date().time() Unique set: ' + nums2.size);

function random10to6th() {
   return Math.random() * Math.pow(10, 6);
}

function random10to6th_concatToTimestamp() {
   return Math.round(new Date().getTime() + '' + (Math.random() * Math.pow(10, 6)));
}
}
<button onclick="run()">Run Algorithms</button>  
<p>(Keep clicking this button)</p>



Aucun commentaire:

Enregistrer un commentaire