Intereting Posts
Doctrine не создает внешние ключи внешней базы данных PHP: формат широты и долготы с градусами, минутами и секундами Каковы допустимые символы в именах PHP, методах, классах и т. Д.? Хранить код html / php в переменной php Загрузите много файлов на клиентской стороне и сжимайте их, затем загрузите файл сжатия на сервер Пересечение многомерных ассоциативных массивов php Почему напечатано последнее число (1)? empty () недействительный обратный вызов? Почему CakePHP использует это имя метода в запросе MySQL, а не возвращает результат? Count Количество запросов Каждая загрузка страницы с PDO Как получить изображения, перечисленные в комплекте соната Присоединение к циклу обработки ошибок Удалить определенные строки из конца строки Как я могу изменить окончания строк, используемые fputcsv? Неустранимая ошибка: вызов неопределенной функции mb_substr ()

Разница между mt_rand () и rand ()

В чем разница между использованием mt_rand($min, $max) и rand($min, $max) относительно скорости?

Обновить

Поскольку PHP 7.1 mt_rand полностью заменил rand , и rand был сделан псевдоним для mt_rand . В ответе ниже рассматриваются различия между двумя функциями для более старых версий и причины введения mt_rand .


Скорость не была причиной появления mt_rand !

Функция rand существовала до mt_rand , но она была глубоко ошибочной. PRNG должен получить некоторую энтропию, число, из которого оно генерирует последовательность случайных чисел. Если вы распечатаете список из десяти чисел, которые были созданы rand() например:

 for ($i=0;$i<10;++$i) echo rand(), PHP_EOL; 

Вывод может использоваться для определения того, что такое семя rand , и с его помощью вы можете предсказать следующие случайные числа. Есть инструменты, которые делают это, поэтому google немного и протестируйте его.

Есть также проблема с rand релятививно быстро показывает шаблоны в своих случайных числах, как показано здесь . Проблема mt_rand похоже, тоже намного лучше.

mt_rand использует лучший алгоритм рандомизации (Mersenne Twist), который требует большего количества случайных чисел до того, как семя может быть определено и быстрее. Это не означает, что mt_rand по определению быстрее, чем rand , это означает, что способ генерации чисел быстрее и, по-видимому, не оказывает реального влияния на производительность функции, как показали другие ответы.
В любом случае, посмотрите на mt_srand и srand docs . Я уверен, что они будут содержать дополнительную информацию

Если алгоритм mt_rand переводится с увеличением производительности, то это здорово для вас, но это счастливое совпадение. TL; TR:

mt_rand был введен для устранения проблем, существующих в rand !

Обновление (PHP 7.1):

rand() и srand() теперь были сделаны aliases для mt_rand() и mt_srand() соответственно. Это означает, что выходные данные для следующих функций имеют изменения: rand() , shuffle() , str_shuffle() и array_rand() .

Это означает, что с версии 7.1 нет никакой практической разницы между обоими из них, потому что rand вызывает mt_rand внутренне .


Перед PHP 7.1:

Использование rand() не является плохой практикой, если оно не используется для целей безопасности, я обычно использую rand() (привычка?).

Если вам нужно огромное количество случайных чисел, вам понадобится mt_rand вместо rand . mt_rand имеет период 2 19937 – 1, намного лучше, чем rand (2 32 ). Взгляните на эту статью о генерации графического шаблона с использованием rand и mt_rand .

Периодичность и энтропия – единственные причины использования mt_rand() вместо rand() а не улучшения безопасности или скорости.

Математически mt_rand имеют большую энтропию и большую периодичность, чем rand (2 19937 -1 против 2 32 ).

Если вам нужны несколько случайных чисел, а безопасность не проблема, rand выполнит эту работу (получите случайное число, чтобы решить, как запустить процесс очистки).


Улучшение скорости тестирования

На практике нет большой разницы в скорости между двумя функциями (возможно, потому, что накладные расходы на PHP⇔C?).

Код проверки PHP:

 <?php for ($c = 0; $c < 3; $c++) { $start = microtime(true); $sum = 0.0; for ($i = 0; $i < 100000000; $i++) { $sum += rand(); } printf('[rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL); } for ($c = 0; $c < 3; $c++) { $start = microtime(true); $sum = 0.0; for ($i = 0; $i < 100000000; $i++) { $sum += mt_rand(); } printf('[mt_rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL); } 

Тесты в PHP 7.0.19:

 $ php timing.php [rand 0] Time: 4.658 s [rand 1] Time: 4.664 s [rand 2] Time: 4.654 s [mt_rand 0] Time: 4.267 s [mt_rand 1] Time: 4.255 s [mt_rand 2] Time: 4.261 s 

Тесты в PHP 5.4.45 (медленная машина):

 $ php timing.php [rand 0] Time: 10.862 s [rand 1] Time: 10.889 s [rand 2] Time: 10.615 s [mt_rand 0] Time: 10.948 s [mt_rand 1] Time: 9.883 s [mt_rand 2] Time: 10.190 s 

Только 6-9%, а не 400%.


Использование в целях безопасности

Но если вашему приложению требуется много энтропии, потому что проблемы безопасности, вам понадобится более безопасный способ, и openssl_random_pseudo_bytes() возможно, является лучшим решением, делает свою работу (гораздо лучше, но медленнее? Нам нужна безопасность по скорости?), Полагаясь на openssl связанных с этим .

Ни rand() ни mt_rand() являются достаточно безопасными :

Внимание. Эта функция не генерирует криптографически защищенные значения и не должна использоваться для криптографических целей. Если вам требуется криптографически безопасное значение, openssl_random_pseudo_bytes() вместо этого использовать random_int() , random_bytes() или openssl_random_pseudo_bytes() .

Существуют расширения PHP, такие как random_compat , но я не рекомендовал их использовать, если это не нужно.

Руководство PHP по mt_rand() сообщает, что оно:

который будет генерировать случайные числа в четыре раза быстрее, чем среднее значение libc rand ().

Начиная с PHP 7.1 нет никакой разницы . rand () теперь является псевдонимом для mt_rand ().

См. http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases

Более подробная информация: https://wiki.php.net/rfc/rng_fixes

Ниже приведена разница в скорости для обоих из них: –
mt_rand($min, $max) в четыре раза быстрее по сравнению с rand($min, $max)

Причина в том, что rand($min, $max) использует генератор случайных чисел libc, а mt_rand($min, $max) использует Mersenne Twister, что в четыре раза быстрее.

Надеюсь, это решит ваши сомнения.
Благодарю.

Они кажутся равными по скорости:

 function timeit($times, $func) { $t = microtime(1); while($times--) $func(); return microtime(1) - $t; } echo PHP_OS, " ", phpversion(), "\n"; echo timeit(100000, function() { rand(0,1000); }), "\n"; echo timeit(100000, function() { mt_rand(0,1000); }), "\n"; 

Результаты для OSX Mavericks и VirtualBox'ed Ubuntu 11:

 Darwin 5.5.19 0.038038969039917 0.033117055892944 Linux 5.3.6-13ubuntu3.10 0.031459093093872 0.031935214996338 

Если эти меры верны, комментарий к руководству, упомянутый в другом месте, должен считаться ошибочным / устаревшим.