在JavaScript中生成大量唯一小随机数的最快方法
想知道如何快速生成许多唯一的、小的随机数。当我像这样实现它时,它的速度似乎呈指数级下降,直到永远无法完成,或者需要几个小时才能完成。可能是因为它在结尾处创建了大量的副本在JavaScript中生成大量唯一小随机数的最快方法,javascript,performance,random,Javascript,Performance,Random,想知道如何快速生成许多唯一的、小的随机数。当我像这样实现它时,它的速度似乎呈指数级下降,直到永远无法完成,或者需要几个小时才能完成。可能是因为它在结尾处创建了大量的副本 var intsmap = {} var intsarray = [] var i = 100000 while (i--) { var int = randominteger(6) if (intsmap[int]) i++ else { intsmap[int] = true intsarray.
var intsmap = {}
var intsarray = []
var i = 100000
while (i--) {
var int = randominteger(6)
if (intsmap[int]) i++
else {
intsmap[int] = true
intsarray.push(int)
}
}
// return intsarray
function randominteger(exp) {
var string = rand(exp)
return pad(string, exp)
}
function pad(num, size) {
var s = rand(9) + num
return s.substr(s.length - size)
}
function rand(exp) {
var integer = Math.random() * Math.pow(10, exp) << 0
var string = toString(integer, '0123456789')
return string
}
function toString(value, code) {
var digit
var radix = code.length
var result = ''
do {
digit = value % radix
result = code[digit] + result
value = Math.floor(value / radix)
} while (value)
return result
}
var intsmap={}
var intsarray=[]
var i=100000
而(我--){
var int=randominteger(6)
if(intsmap[int])i++
否则{
intsmap[int]=真
intsarray.push(int)
}
}
//返回intsarray
函数随机整数(exp){
变量字符串=rand(exp)
返回垫(字符串,exp)
}
功能板(数量、大小){
var s=兰特(9)+num
返回s.substr(s.length-size)
}
函数rand(exp){
var integer=Math.random()*Math.pow(10,exp)var acc=0;
常量结果=[];
对于(变量i=0;i<100000;i++)
结果推送(acc+=Math.floor(Math.random()*10)+1);
我认为最昂贵的操作是哈希表查找/插入,因此只需不使用它就可以了。您可以使用对象作为查找,只插入唯一的随机数
var intsmap={};
var i=100000;
而(我--){
var int=Math.random()*Math.pow(10,6)如果需要唯一的大数组,请尝试以其他方式思考。只需创建范围0…100000并将其洗牌,然后应用此数组所需的函数。只需尝试将数字数组1洗牌为maxNum
首先创建一个数组
var maxNum = 1000000;
var arr = Array(maxNum).fill().map((e,i)=>i+1);
现在洗牌数组
arr.sort(function() {
return .5 - Math.random();
});
现在有了唯一随机数的数组
演示
var startTime=new Date().getTime();
var maxNum=1000000;
var arr=Array(maxNum).fill().map((e,i)=>i+1);
arr.sort(函数(){
return.5-Math.random();
});
var endTime=new Date().getTime();
console.log(“获取“+maxNum+”大小的随机唯一数字所用的时间为“+(endTime-startTime)+”ms”);
可能会影响性能的一个地方是Math.random
调用。
这是一个相当昂贵的调用,您需要多次调用才能生成字符串
利用它的一个解决方案是从Math.random()
的单个结果中获取整个字符串
var intsmap={}
var intsarray=[]
var i=100000
而(我--){
var int=randominteger(6)
if(intsmap[int]){
我++
}否则{
intsmap[int]=真
intsarray.push(int)
}
}
console.log(intsarray);
//它将单个调用中的整个字符串转换为“random”。
//最大长度为16。
函数随机整数(长度){
返回(Math.random()+“”).substr(2,长度);
}
我可以提出以下方法:
- 生成一个随机数
- 将其转换为字符串(0.1234567812345678)
- 并提取长度为10的6个子串
代码:
var res={},
s=“”;
对于(设i=0;如果对我来说,上面的代码在40-100ms
之间,你期待什么?你的退出条件是i
达到0
。你想要100000
随机数吗?对不起,方法实现完全改变了它,哇。更新了问题。@LancePollard你说的是什么方法实现ut?@LancePollard然后只是乱序数字。问题的原因是执行速度慢。请参阅randomnumber
。您错过了更新部分。OP不需要数字。@Kaido已经要求OP澄清了一点。方法与之几乎相同,但更进一步;-)从中提取6个字符串是个好主意,但您在这里没有检查冲突。为什么要检查冲突?我会对少于2000个冲突进行1000000次以上的检查。它们是唯一的。提取res
中的前1000000次并检查它们;)好吧,我明白了,你计算的比需要的要多,只得到需要的数字。我不知道我对这个想法有何感想…@kaido-throughacc
?!
arr.sort(function() {
return .5 - Math.random();
});
var res = {},
s = "";
for (let i=0; i<1000000; ++i) {
s = Math.random().toString();
for (let j=0; j<6; ++j) {
res[s.substring(2+j, 12+j)] = true; // extract 10 digits
}
}