如何写出最快的循环


·        作者Laruence(   )

·        本文地址http://www.laruence.com/2009/04/07/670.html

·        转载请注明出处

你知道怎么写出最快的循环么?

刚刚在晓东郭的blog看到一个有趣的问题 PHP $i++ ++$i 的区别 “:

1.       方式一:

2.        

3.       $begin = time();

4.       $i = 0;

5.       while(++$i < 10000)

6.       {

7.         $j = 0;

8.         while(++$j < 10000)

9.           ;

10.      ;

11.    }

12.    $end = time();

13.     

14.    时间 : 16s

15.     

16.    方式二:

17.     

18.    $begin = time();

19.    $i = 0;

20.    while($i < 10000)

21.    {

22.      $j = 0;

23.      while($j < 10000)

24.        ++$j;

25.      ++$i;

26.    }

27.    $end = time();

28.     

29.    时间:13s

30.     

31.    方式三:

32.     

33.    $begin = time();

34.    $i = 0;

35.    while($i < 10000)

36.    {

37.      $j = 0;

38.      while($j < 10000)

39.        $j++;

40.      $i++;

41.    }

42.    $end = time();

43.     

44.    时间:15s

45.     

46.    方式四:

47.     

48.    $begin = time();

49.    $i = 0;

50.    while($i++ < 10000)

51.    {

52.      $j = 0;

53.      while($j++ < 10000)

54.        ;

55.      ;

56.    }

57.    $end = time();

58.    时间:13s

呵呵, 为什么会这样呢?
对比第一种方法和第二种方法,因为在PHP, 最终被执行的是OPCODE,每行opline都有俩个操作数, 对于操作数来说, 一般有3种类型的存取方式, 临时变量, 变量, 和编译时变量, 这三种变量其中, 存取最快的是第三种, 编译器变量, OpCode执行过程中, 会讲一个变量的加一级引用存储在一个hash结构中, 用来加快存取速度.

在第一种方法中:

1.       $i = 0;

2.       while(++$i < 10000)

3.       {

4.         $j = 0;

5.         while(++$j < 10000)

6.           ;

7.         ;

8.       }

因为对于++$i来说, 我们需要得到它的返回值, 来和10000做比较, 这样就会使得PHP在编译的时候 , 生成一个变量(IS_VAR), 来保存自增的结果 , 也就是说, 这个时候用到了oplinereturn操作数.
然后, PHP会拿这个变量(IS_VAR)来和10000做比较.

而对于第二种方式:

1.       $i = 0;

2.       while($i < 10000)

3.       {

4.         $j = 0;

5.         while($j < 10000)

6.           ++$j;

7.         ++$i;

8.       }

这个过程中, $i已经优化成了编译变量(IS_CV), 而对于++$i, 因为我们不需要保存他的返回值, 所以也只是直接对编译变量进行自增..

也就是说, 方法一和方法二的速度差异, 就在于对于方式二, 我们一直都在实用编译变量.. 编译变量的存取速度远快于变量(IS_VAR)

再来看第三种和第四种方式:

1.       //3:

2.       $i = 0;

3.       while($i < 10000)

4.       {

5.         $j = 0;

6.         while($j < 10000)

7.           $j++;

8.         $i++;

9.       }

10.     

11.    //4:

12.    $i = 0;

13.    while($i++ < 10000)

14.    {

15.      $j = 0;

16.      while($j++ < 10000)

17.        ;

18.      ;

19.    }

我们知道后缀自增(POST_INC), 会返回一个对原值的copy, 然后自增.
对于第四种方式, $i++以后, ZE会将$i的原值, 存储在一个临时变量(IS_TMP_VAR).并且会拿这个临时变量和10000对比.
所以, 严格来讲, 这部分的速度比起第一种方式来说是会慢一些的.

而第三种方式慢在, 因为对$i++的返回值没有使用, 在语法分析阶段, $j++会归约成(rw_variable T_INC->expr_without_variable->expr,expr+’;’ => zend_do_free). 所以ZE就会安排一条opline, free掉这个临时变量….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值