Re: [請益] php使用迴圈的效率
※ 引述《star508 (star)》之銘言:
: 今天有碰到一個問題,不知道有沒有人可以幫我解惑?
: 有一個抽獎活動,共有九個獎項個別有設定好抽獎的機率,
: 我是取一到一千的亂數,依照取得的亂數決定獎項,程式碼如下:
: //九個獎項從第一獎到第九獎機率為2%,10%,15%,0.3%,0.7%,2%,10%,20%,40%
: $prizeRange=array{0,20,100,150,3,7,20,100,200,400};
: $randNo=mt_rand(1,1000);//從一到一千隨機取出一數字
: $prizeNo=0;//從下方程式判斷得第幾獎
: //方法一(慢)
: while($randNo>0){$randNo-=$prizeRang[$prizeNo+1];$prizeNo++;}
: //方法二(快)
: for($i=1;$i<count($prizeRange);$i++}
: {
: $randNo=$randNo-$prizeRange[$i];
: if ($randNo<=0) {$prizeNo=$i;break;}
: }
: //
: 本來是用第一種方法,但是實際放上server執行時發現執行速度超慢,還會出現超過
: 超過30秒沒回應的error,
: 後來改成第二種方法讓迴圈有實際的次數去跑,結果速度差很多,就算再寫個for迴圈
: 跑個2000次也是一開網頁就有執行結果,不知道到底為何結果差這麼多,照理說迴圈
: 執行的次數應該差不多啊,不知道有沒有人可以幫我解答,Tks!
O()不同?在下看起來覺得一樣啊@@
(最差狀況下迴圈都只會執行count($prizeRange)-1次,即O()=n)
實際在cli環境下用time去計時也是得到差不多的結論
以下是測試資料
(有做一點程式碼簡化,並改為重複執行10萬次,使用php5 on Debian lenny測試
方法一:
$p=array(0,20,100,150,3,7,20,100,200,400);
for($j=0;$j<100000;$j++)
{
$a=mt_rand(1,1000);
$r=0;
while($a>0)
$a-=$p[++$r];
}
結果
real 0m0.428s
user 0m0.412s
sys 0m0.020s
方法二:
$p=array(0,20,100,150,3,7,20,100,200,400);
for($j=0;$j<100000;$j++)
{
$a=mt_rand(1,1000);
$r=0;
for($r=1;$r<10;$r++)
{
$a-=$p[$r];
if($a<=0)break;
}
}
結果
real 0m0.518s
user 0m0.496s
sys 0m0.020s
此處我將prizeRange固定,否則加上10萬次count($p)所花的時間,兩者差距會更大
以上可知方法一還比較快,這是因為方法一少做一次條件判斷的關係
由此推論,原po有可能是方法一的原始碼有筆誤造成了無窮迴圈
此外若把方法二小小修改一下便可得到與方法一相同的速度
$p=array(0,20,100,150,3,7,20,100,200,400);
for($j=0;$j<100000;$j++)
{
$a=mt_rand(1,1000);
for($r=0;$a>0;$a-=$p[++$r]);
}
結果:
real 0m0.433s
user 0m0.404s
sys 0m0.028s
結果較方法一慢上一點點,這是php本身interpreting的轉換公式造成的
單以語言邏輯而言,此一修改後的程式碼是與方法一等價的
而理論上最快的應該是
$p=array(0,20,120,270,273,280,300,400,600,1000);
for($j=0;$j<100000;$j++)
{
$a=mt_rand(1,1000);
$r=1;
while($a<=$p[$r])$r++;
}
結果
real 0m0.209s
user 0m0.188s
sys 0m0.020s
這是因為比方法一再少了一次減法運算的關係
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.62.104.89
※ 編輯: ronmi 來自: 61.62.104.89 (06/26 03:38)
推
06/26 03:47, , 1F
06/26 03:47, 1F
討論串 (同標題文章)
PHP 近期熱門文章
PTT數位生活區 即時熱門文章