作者ronmi (Love.みけ)
看板PHP
标题Re: [请益] php使用回圈的效率
时间Thu Jun 26 03:10:07 2008
※ 引述《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)
1F:推 JoeHorn :sorry,没仔细看。 方法一的问题出在阵列名称错误。 06/26 03:47