关于for,while,dowhile效率测试

引言

  大家都知道每种循环对应的效率是不同的,书中都说在循环中使用减法的效率是比加法的效率高的,具体情况是怎么样,我们将详细列出各循环的执行效率问题。本文通过查看汇编代码比较各循环的效率以及i++,++i,i--,--i在循环中使用的效率问题,仅供抛砖引玉,测试平台为intel i5 4440,编译器为gcc-4.8.2

 

测试代码1

  此段代码我们主要测试在i--,--i,i++,++i的情况下,for循环、dowhile循环、while循环之间的执行效率情况

 1 #include <stdio.h>

 2 

 3 /* 用于测试i--的while,for,dowhile循环情况 */

 4 void minus1 (void)

 5 {

 6     int i = 10;

 7 

 8     /* i-- while循环 */

 9     while (i--)

10         ;

11 

12     i = 10;

13 

14     /* i-- dowhile循环 */

15     do

16         ;

17     while (i--);

18 

19     /* i-- for循环 */

20     for (i = 10; i != 0; i--)

21         ;

22 }

23 

24 /* 用于测试--i的while,for,dowhile循环情况 */

25 void minus (void)

26 {

27     int i = 10;

28 

29     /* --i while循环 */

30     while (--i)

31         ;

32 

33     i = 10;

34 

35     /* --i dowhile循环 */

36     do

37         ;

38     while (--i);

39 

40     /* --i for循环 */

41     for (i = 10; i != 0; --i)

42         ;

43 }

44 

45 /* 用于测试i++的while,for,dowhile循环情况 */

46 void plus1 (void)

47 {

48     int i = 0;

49 

50     /* i++ while循环 */

51     while (i++ < 10)

52         ;

53 

54     i = 0;

55 

56     /* i++ dowhile循环 */

57     do

58         ;

59     while (i++ < 10);

60 

61     /* i++ for循环 */

62     for (i = 0; i < 10; i++)

63         ;

64 }

65 

66 /* 用于测试++i的while,for,dowhile循环情况 */

67 void plus (void)

68 {

69     int i = 0;

70 

71     /* ++i while循环 */

72     while (++i < 10)

73         ;

74 

75     i = 0;

76 

77     /* ++i dowhile循环 */

78     do

79         ;

80     while (++i < 10);

81 

82     /* ++i for循环 */

83     for (i = 0; i < 10; ++i)

84         ;

85 }

86 

87 

88 int main (int argc, char * argv[])

89 {

90     return 0;

91 }

 

测试代码1所生成的汇编代码如下:

  1 #include <stdio.h>

  2 

  3 void minus1 (void)

  4 {

  5   4004ed:    55                       push   %rbp

  6   4004ee:    48 89 e5                 mov    %rsp,%rbp

  7     int i = 10;

  8   4004f1:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)         # i = 10

  9 

 10     while (i--)                                                        # while (i--)

 11   4004f8:    90                       nop                              # 空指令

 12   4004f9:    8b 45 fc                 mov    -0x4(%rbp),%eax            # eax = i                                     主循环

 13   4004fc:    8d 50 ff                 lea    -0x1(%rax),%edx            # edx = rax - 1(rax的低32位为eax)              主循环

 14   4004ff:    89 55 fc                 mov    %edx,-0x4(%rbp)            # i = edx                                     主循环

 15   400502:    85 c0                    test   %eax,%eax                  # 等同于(i & i), 如果i不等于0,则结果也不为0       主循环

 16   400504:    75 f3                    jne    4004f9 <minus1+0xc>        # 不等于0则跳转至4004f9                         主循环

 17         ;

 18 

 19     i = 10;

 20   400506:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)            # i = 10

 21 

 22     do

 23         ;

 24     while (i--);                                                        # do ... while (i--); 

 25   40050d:    8b 45 fc                 mov    -0x4(%rbp),%eax            # eax = i                                      主循环

 26   400510:    8d 50 ff                 lea    -0x1(%rax),%edx            # edx = rax - 1(rax的低32位为eax)               主循环

 27   400513:    89 55 fc                 mov    %edx,-0x4(%rbp)            # i = edx                                      主循环

 28   400516:    85 c0                    test   %eax,%eax                  # 等同于(i & i), 如果i不等于0,则结果也不为0        主循环

 29   400518:    75 f3                    jne    40050d <minus1+0x20>       # 不等于0则跳转至40050d                          主循环

 30 

 31     for (i = 10; i != 0; i--)                                           # for (i = 10; i != 0; i--)

 32   40051a:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)            # i = 10

 33   400521:    eb 04                    jmp    400527 <minus1+0x3a>       # 跳转至400527

 34   400523:    83 6d fc 01              subl   $0x1,-0x4(%rbp)            # i = i - 1                                    主循环

 35   400527:    83 7d fc 00              cmpl   $0x0,-0x4(%rbp)            # i与0进行比较                                 主循环

 36   40052b:    75 f6                    jne    400523 <minus1+0x36>       # 比较结果不等于0则跳转至400523                主循环

 37         ;

 38 }

 39 

 40 void minus (void)

 41 {

 42   40052f:    55                       push   %rbp

 43   400530:    48 89 e5                 mov    %rsp,%rbp

 44     int i = 10;

 45   400533:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)

 46 

 47     while (--i)                                                         # while (--i) 

 48   40053a:    83 6d fc 01              subl   $0x1,-0x4(%rbp)            # i = i - 1                        主循环

 49   40053e:    83 7d fc 00              cmpl   $0x0,-0x4(%rbp)            # i与0比较                         主循环

 50   400542:    75 f6                    jne    40053a <minus+0xb>         # 比较结果不等于0则跳转至40053a              主循环

 51         ;

 52 

 53     i = 10;

 54   400544:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)

 55 

 56     do

 57         ;

 58     while (--i);                                                        # do ... while (--i);

 59   40054b:    83 6d fc 01              subl   $0x1,-0x4(%rbp)            # i = i - 1                                 主循环

 60   40054f:    83 7d fc 00              cmpl   $0x0,-0x4(%rbp)            # i与0比较                                 主循环

 61   400553:    75 f6                    jne    40054b <minus+0x1c>        # 比较结果不等于0则跳转至40054b                 主循环

 62 

 63     for (i = 10; i != 0; --i)                                           # for (i = 10; i != 0; --i)

 64   400555:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)            # i = 10

 65   40055c:    eb 04                    jmp    400562 <minus+0x33>        # 跳转至400562

 66   40055e:    83 6d fc 01              subl   $0x1,-0x4(%rbp)            # i = i - 1                                主循环

 67   400562:    83 7d fc 00              cmpl   $0x0,-0x4(%rbp)            # i与0比较                                   主循环

 68   400566:    75 f6                    jne    40055e <minus+0x2f>        # 比较结果不等于0则跳转至40055e                 主循环

 69         ;

 70 }

 71 

 72 void plus1 (void)

 73 {

 74   40056a:    55                       push   %rbp

 75   40056b:    48 89 e5                 mov    %rsp,%rbp

 76     int i = 0;

 77   40056e:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)

 78 

 79     while (i++ < 10)                                                    # while (i++ < 10)     

 80   400575:    90                       nop

 81   400576:    8b 45 fc                 mov    -0x4(%rbp),%eax            # eax = i                                 主循环

 82   400579:    8d 50 01                 lea    0x1(%rax),%edx             # edx = rax + 1(rax的低32位为eax)         主循环

 83   40057c:    89 55 fc                 mov    %edx,-0x4(%rbp)            # i = edx                                主循环

 84   40057f:    83 f8 09                 cmp    $0x9,%eax                  # eax与9比较                              主循环

 85   400582:    7e f2                    jle    400576 <plus1+0xc>         # 比较结果不成立则跳转至400576              主循环

 86         ;

 87 

 88     i = 0;

 89   400584:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)

 90 

 91     do

 92         ;

 93     while (i++ < 10);                                                   # while (i++ < 10);

 94   40058b:    8b 45 fc                 mov    -0x4(%rbp),%eax            # eax = i                                    主循环 

 95   40058e:    8d 50 01                 lea    0x1(%rax),%edx             # edx = rax + 1(rax的低32位为eax)             主循环

 96   400591:    89 55 fc                 mov    %edx,-0x4(%rbp)            # i = edx                                    主循环

 97   400594:    83 f8 09                 cmp    $0x9,%eax                  # eax与9比较                                  主循环

 98   400597:    7e f2                    jle    40058b <plus1+0x21>        # 比较结果不成立则跳转至40058b                  主循环

 99 

100     for (i = 0; i < 10; i++)                                            # for (i = 0; i < 10; i++)

101   400599:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)            # i = 0                                         

102   4005a0:    eb 04                    jmp    4005a6 <plus1+0x3c>        # 跳转至4005a6                                     

103   4005a2:    83 45 fc 01              addl   $0x1,-0x4(%rbp)            # i = i + 1                                  主循环

104   4005a6:    83 7d fc 09              cmpl   $0x9,-0x4(%rbp)            # i与9比较                                    主循环

105   4005aa:    7e f6                    jle    4005a2 <plus1+0x38>        # 比较结果不成立则跳转至4005a2                  主循环

106         ;

107 }

108 

109 void plus (void)

110 {

111   4005ae:    55                       push   %rbp

112   4005af:    48 89 e5                 mov    %rsp,%rbp

113     int i = 0;

114   4005b2:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)

115 

116     while (++i < 10)                                                    # while (++i < 10)

117   4005b9:    83 45 fc 01              addl   $0x1,-0x4(%rbp)            # i = i + 1                                   主循环

118   4005bd:    83 7d fc 09              cmpl   $0x9,-0x4(%rbp)            # i与9比较                                     主循环

119   4005c1:    7e f6                    jle    4005b9 <plus+0xb>          # 比较结果不成立则跳转至4005b9                   主循环

120         ;

121 

122     i = 0;

123   4005c3:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)

124 

125     do

126         ;

127     while (++i < 10);                                                   # while (++i < 10);

128   4005ca:    83 45 fc 01              addl   $0x1,-0x4(%rbp)            # i = i + 1                                   主循环

129   4005ce:    83 7d fc 09              cmpl   $0x9,-0x4(%rbp)            # i与9比较                                     主循环

130   4005d2:    7e f6                    jle    4005ca <plus+0x1c>         # 比较结果不成立则跳转至4005b9                   主循环

131 

132     for (i = 0; i < 10; ++i)                                            # for (i = 0; i < 10; ++i)

133   4005d4:    c7 45 fc 00 00 00 00     movl   $0x0,-0x4(%rbp)            # i = 0

134   4005db:    eb 04                    jmp    4005e1 <plus+0x33>         # 跳转至4005e1

135   4005dd:    83 45 fc 01              addl   $0x1,-0x4(%rbp)            # i = i + 1                                   主循环

136   4005e1:    83 7d fc 09              cmpl   $0x9,-0x4(%rbp)            # i与9比较                                     主循环

137   4005e5:    7e f6                    jle    4005dd <plus+0x2f>         # 比较结果不成立则跳转至4005dd                   主循环

138         ;

139 }

 

可以从汇编代码得出如下表格

  while主循环语句数

do...while主循环语句数

for主循环语句数
i-- 5 5 3
--i 3 3 3
i++ 5 5 3
++i 3 3 3

 

 

小结

  可以从表中得出结论:循环效率最高也需要执行3条汇编语句,而最慢需要5条汇编语句,使用i--和i++进行循环控制时,不同的循环结构所对应的汇编代码量不同,最少的为for循环,只需要3条汇编指令,最多的为while循环,需要5条汇编指令,而当使用--i和++i进行循环控制时,无论哪一种循环结构执行效率都一样是最优的,都只需要3条代码,而无论使用i--,--i,i++,++i中哪一种,for循环的效率应该是最高的,都只用了3条汇编代码。

 

你可能感兴趣的:(while)