關於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條匯編代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM