速度に関するmt_Rand($min, $max)
とRand($min, $max)
の使用の違いは何ですか?
PHP 7.1 mt_Rand
はRand
に完全に取って代わり、Rand
はmt_Rand
のエイリアスになりました。以下の回答は、古いバージョンの2つの関数の違いとmt_Rand
を導入する理由に焦点を当てています。
mt_Rand
が導入された理由は速度ではありませんでした!Rand
関数はmt_Rand
の前に存在していましたが、重大な欠陥がありました。 A PRNGいくつかのエントロピーを取得する必要があります。これは乱数のシーケンスを生成する数値です。Rand()
によって生成された10個の数値のリストを出力する場合:
for ($i=0;$i<10;++$i)
echo Rand(), PHP_EOL;
出力を使用して、Rand
シードが何であったかを調べることができ、それを使用して、次の乱数を予測できます。これを行うツールがありますので、少しグーグルでテストしてください。
ここに示されているように、Rand
には、そのパターンの乱数 が比較的迅速に表示されるという問題もあります 。 mt_Rand
の問題も、はるかに改善されているようです。
mt_Rand
は、より良いランダム化アルゴリズム(Mersenne Twist)を使用します。これは、シードを決定する前に、より多くの乱数を知る必要があります and は高速です。 これは、定義により、mt_Rand
がRand
is よりも高速であることを意味するものではなく、数値の生成方法が高速であり、ここでの他の回答が示しているように、関数のパフォーマンスに実際の影響はありません。
どちらの方法でも、 mt_srand
と srand
docs をご覧ください。もっと情報が含まれていると確信しています
mt_Rand
のアルゴリズムがパフォーマンスの向上につながる場合、それはあなたにとって素晴らしいことですが、それは幸運な偶然です。 TL; TR:
mt_Rand
は、Rand
に存在する問題を修正するために導入されました!
Rand()
とsrand()
は、それぞれmt_Rand()
とmt_srand()
のエイリアスになりました。 これは、次の関数の出力には変更があります:Rand()
、shuffle()
、str_shuffle()
、およびarray_Rand()
。
つまり、バージョン7.1以降では、 Rand
がmt_Rand
を内部的に呼び出すため 、両者の間に実質的な違いはありません。
Rand()
を使用することは、セキュリティ目的で使用しない場合、悪い習慣ではありません。通常、Rand()
(習慣?)を使用しています。
大量の乱数が必要な場合は、Rand
の代わりにmt_Rand
が必要になります。 mt_Rand
の期間は2です19937 − 1、Rand
(232)。 Rand
およびmt_Rand
を使用したグラフィカルパターン生成については、 この記事 をご覧ください。
Periodicity および entropy がmt_Rand()
の代わりにRand()
を使用する唯一の理由ですセキュリティや速度の改善ではありません。
数学的にmt_Rand
は、Rand
(2)よりも多く エントロピー およびより大きい 周期性19937−1対232)。
あなたは、いくつかの乱数を必要とし、セキュリティが問題、Rand
でない場合(クリーンアッププロセスを発射決定する乱数を取得する)仕事を行います。
実際には、2つの関数の速度に大きな違いはありません(おそらく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
主張どおり400%ではなく6-9%のみ。
ただし、セキュリティの問題のためにアプリケーションで多くのエントロピーが必要な場合は、より安全な方法が必要であり、 openssl_random_pseudo_bytes()
が最善のソリューションであり、その作業を行います(はるかに良いが遅い?速度よりもセキュリティが必要?) openssl関連の問題に依存している 。
Rand()
もmt_Rand()
も十分に安全ではありません:
Cautionこの関数は暗号的に安全な値を生成しないため、暗号化の目的には使用しないでください。暗号的に安全な値が必要な場合は、代わりに
random_int()
、random_bytes()
、またはopenssl_random_pseudo_bytes()
の使用を検討してください。
PHP random_compat
のような拡張機能がありますが、必要でない場合は使用しないことをお勧めします。
PHP 7.1の時点でまったく違いはありません。Rand()はmt_Rand()のエイリアスになりました。
http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.Rand-srand-aliases を参照してください
mt_Rand()
のPHPマニュアルは次のように述べています:
これは、平均的なlibc Rand()が提供するものの4倍の速度で乱数を生成します。