admin 管理员组文章数量: 1086019
I am using the following JS function to generate unique IDs, which I got from another StackOverflow thread:
function generateUniqueID() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
I see that it bines the current Date/Time with an additional Randomizer.
Nonetheless, I verified that I'm getting collisions on every 4th or 5th operation of quickly adding items with IDs.
The function is called inside a JS loop to generate IDs from the list of current elements.
jQuery.each(mainEvents, function(index, item) {
// ...
// Generate gaps
gapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"other" : other });
}
Is this function unreliable? Could it allow collisions in quick JS loop iterations?
I've pretty much ruled out "outside causes" (i.e. that this function isn't the culprit but something else could be), but if that's the case, I can't understand why Math.random()
wouldn't keep me safe.
I am using the following JS function to generate unique IDs, which I got from another StackOverflow thread:
function generateUniqueID() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
I see that it bines the current Date/Time with an additional Randomizer.
Nonetheless, I verified that I'm getting collisions on every 4th or 5th operation of quickly adding items with IDs.
The function is called inside a JS loop to generate IDs from the list of current elements.
jQuery.each(mainEvents, function(index, item) {
// ...
// Generate gaps
gapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"other" : other });
}
Is this function unreliable? Could it allow collisions in quick JS loop iterations?
I've pretty much ruled out "outside causes" (i.e. that this function isn't the culprit but something else could be), but if that's the case, I can't understand why Math.random()
wouldn't keep me safe.
- Indeeed.I tried that on a 10000 items array.When I created a set from that array it kept only about 119 values out of 10000 – Manos Kounelakis Commented Jan 15, 2018 at 22:46
- But why isn't it working? Of course these are pseudo-random numbers, but still we don't expect collisions to be as frequent as this? – gene b. Commented Jan 15, 2018 at 22:50
- 1 The date probably isn't helping, it loops executes so fast it should probably be the same value for each item. Not sure why 20% of ids would consistently be the same, but I would expect at least 1% to be the same. If you want to roll your own function you can use an ES6 Set to easily keep track of unique ids, though. – adamz4008 Commented Jan 15, 2018 at 22:59
4 Answers
Reset to default 3Very much so. You can use new Date().getTime()
to get a unique id under the assumption that it takes longer than 1ms for each iteration. As you can tell from your data, that is false. Combined with an RNG that uses Math.floor
, it's very possible to get repeated values. You will get repeat times whenever the interval is < 1ms. If you want unique IDs based around the concept of an RNG, I'd say just using Math.random()
to the 10^15 is a better choice. 10^15 is the max size integer digit length that will never go past Number.MAX_SAFE_INTEGER
.
Math.floor(Math.random() * Math.pow(10, 15))
Is this function unreliable?
In my opinion it really is.
Infact new Date().getTime()
is an integer number that increases by 1 each millisecond, while Math.random() * 100
is a pseudo random number that gives a number in a range from 0 to 99.
So their sum might really repeat often if the function is called many times rapidly.
Think if the function is called two times per millisecond, it bees very likely to have the same number twice. It has 1/100 of probability to happen (and these are pretty much the results I'm getting considering that I'm generating a list of 10.000 ids in about 1 second using that function and getting ~100 duplicates, which is pretty consistent as order of magnitude)
A random value is never
a unique value. Even with a timestamp you can't guarantee that the oute is 100% unique. However, you could minimize this by generating a larger (random) value.
Using a timestamp however, you cover yourself when there are multiple pushes at the same time. Using an extra random will create an almost unique value which, in most use cases is unique.
I'd suggest though to make that random value longer. Or create a GUID instead.
Create GUID / UUID in JavaScript?
Based on the responses the following pares the suggested methods.
But I think I'm going in the wrong direction for my needs. I will be using the ID/Sequence on the server-side to ensure uniqueness.
function run() {
var nums1 = new Set(), nums2 = new Set(), nums3 = new Set();
for (var i = 0; i < 10000; i++) {
nums1.add(originalMethod());
}
for (var i = 0; i < 10000; i++) {
nums2.add(concatMethod());
}
for (var i = 0; i < 10000; i++) {
nums3.add(random10To18thMethod());
}
console.clear();
console.log('Original Method set: ' + nums1.size);
console.log('Concat Method set: ' + nums2.size);
console.log('Math.Random 10^18 set: ' + nums3.size);
function originalMethod() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
function concatMethod() {
return Math.round(new Date().getTime() + '' + (Math.random() * 100));
}
function random10To18thMethod() {
return Math.random() * Math.pow(10, 18);
}
}
<button onclick="run()">Run Algorithms</button>
本文标签: javascriptIs this JS Unique ID Generator Unreliable (Getting collisions)Stack Overflow
版权声明:本文标题:javascript - Is this JS Unique ID Generator Unreliable? (Getting collisions) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744024229a2520347.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论