Мне нужно разработать способ создания 10000 неповторяющихся случайных чисел в PHP, а затем поместить их в таблицу базы данных. Номер будет состоять из 12 цифр.
Как лучше всего это сделать?
Мне нужно разработать способ создания 10000 неповторяющихся случайных чисел в PHP, а затем поместить их в таблицу базы данных. Номер будет состоять из 12 цифр.
Как лучше всего это сделать?
Это предполагает, что вы можете без проблем сгенерировать 12-значное случайное число (используйте getrandmax (), чтобы узнать, насколько большим вы можете получить ... согласно php.net, в некоторых системах 32k - это максимальное число, которое вы можете получить.
$array = array();
while(sizeof($array)<=10000){
$number = mt_rand(0,999999999999);
if(!array_key_exists($number,$array)){
$array[$number] = null;
}
}
foreach($array as $key=>$val){
//write array records to db.
}
Вы можете использовать rand () или mt_rand (). Однако предполагается, что mt_rand () будет быстрее.
in_array()
, который замедлил бы это по мере увеличения числа генерируемых чисел. Просто используйте число в качестве ключа массива, что уменьшает количество повторяющихся проверок до if isset($array[$number]) { ... }
.
- person Marc B; 09.02.2011
in_array
Я считаю, что это требует линейного времени, поэтому весь алгоритм занимает квадратичное время. Сказав $array[$number] = null;
и используя вместо этого array_key_exists
, вы получите значительно лучшую производительность (близкую к линейной).
- person erisco; 09.02.2011
При длине 12 цифр я не думаю, что вероятность получения повторов очень велика. Я бы, вероятно, просто сгенерировал числа, попытался бы вставить их в таблицу, и, если он уже существует (при условии, что у вас есть уникальное ограничение для этого столбца), просто сгенерируйте еще одно.
Прочтите, например, 40000 (= PHP_INT_SIZE * 10000) байт из /dev/random
сразу, затем разделите его, разбейте на модули (оператор %
), и вот оно.
Затем отфильтруйте и повторите процедуру.
Это позволяет избежать слишком большого количества системных вызовов / переключений контекста (между средой выполнения php, движком zend и самой операционной системой - я не буду здесь вдаваться в подробности).
Это должен быть наиболее эффективный способ сделать это.
/dev/random
. Меня беспокоит только переносимость. Очевидно, это не будет работать с окнами и может не работать, если действует open_basedir
ограничение.
- person Eric Petroelje; 09.02.2011
unpack()
- это путь. Как вы понимаете, производительность на всем пути с моим методом. У вас есть повторитель, поэтому в среде выполнения PHP нет циклов, циклы выполняются ЦП напрямую (через двоичный файл PHP).
- person Flavius; 12.02.2011
/dev/urandom
не возвращал мне хотя бы один повторяющийся номер из этих 10000. /dev/random
хотя и медленный. Я могу отредактировать свой ответ, если вы хотите увидеть POC. Никаких циклов, только чистая скорость - по крайней мере, на стороне PHP.
- person Flavius; 14.02.2011
Сгенерируйте 10000 случайных чисел и поместите их в массив. Пропустите массив через array_unique
. Проверьте длину. Если меньше 10000, добавьте еще несколько штук. Пропустить массив через array_unique
. Если больше 10000, то пробегите array_slice
, чтобы получить 10000. В противном случае вспенить, промыть, повторить.