关于for,while,dowhile效率测试
引言
大家都知道每種循環(huán)對(duì)應(yīng)的效率是不同的,書中都說在循環(huán)中使用減法的效率是比加法的效率高的,具體情況是怎么樣,我們將詳細(xì)列出各循環(huán)的執(zhí)行效率問題。本文通過查看匯編代碼比較各循環(huán)的效率以及i++,++i,i--,--i在循環(huán)中使用的效率問題,僅供拋磚引玉,測(cè)試平臺(tái)為intel i5 4440,編譯器為gcc-4.8.2
測(cè)試代碼1
此段代碼我們主要測(cè)試在i--,--i,i++,++i的情況下,for循環(huán)、dowhile循環(huán)、while循環(huán)之間的執(zhí)行效率情況
1 #include <stdio.h>
2
3 /* 用于測(cè)試i--的while,for,dowhile循環(huán)情況 */
4 void minus1 (void)
5 {
6 int i = 10;
7
8 /* i-- while循環(huán) */
9 while (i--)
10 ;
11
12 i = 10;
13
14 /* i-- dowhile循環(huán) */
15 do
16 ;
17 while (i--);
18
19 /* i-- for循環(huán) */
20 for (i = 10; i != 0; i--)
21 ;
22 }
23
24 /* 用于測(cè)試--i的while,for,dowhile循環(huán)情況 */
25 void minus (void)
26 {
27 int i = 10;
28
29 /* --i while循環(huán) */
30 while (--i)
31 ;
32
33 i = 10;
34
35 /* --i dowhile循環(huán) */
36 do
37 ;
38 while (--i);
39
40 /* --i for循環(huán) */
41 for (i = 10; i != 0; --i)
42 ;
43 }
44
45 /* 用于測(cè)試i++的while,for,dowhile循環(huán)情況 */
46 void plus1 (void)
47 {
48 int i = 0;
49
50 /* i++ while循環(huán) */
51 while (i++ < 10)
52 ;
53
54 i = 0;
55
56 /* i++ dowhile循環(huán) */
57 do
58 ;
59 while (i++ < 10);
60
61 /* i++ for循環(huán) */
62 for (i = 0; i < 10; i++)
63 ;
64 }
65
66 /* 用于測(cè)試++i的while,for,dowhile循環(huán)情況 */
67 void plus (void)
68 {
69 int i = 0;
70
71 /* ++i while循環(huán) */
72 while (++i < 10)
73 ;
74
75 i = 0;
76
77 /* ++i dowhile循環(huán) */
78 do
79 ;
80 while (++i < 10);
81
82 /* ++i for循環(huán) */
83 for (i = 0; i < 10; ++i)
84 ;
85 }
86
87
88 int main (int argc, char * argv[])
89 {
90 return 0;
91 }
測(cè)試代碼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 主循環(huán)
13 4004fc: 8d 50 ff lea -0x1(%rax),%edx # edx = rax - 1(rax的低32位為eax) 主循環(huán)
14 4004ff: 89 55 fc mov %edx,-0x4(%rbp) # i = edx 主循環(huán)
15 400502: 85 c0 test %eax,%eax # 等同于(i & i), 如果i不等于0,則結(jié)果也不為0 主循環(huán)
16 400504: 75 f3 jne 4004f9 <minus1+0xc> # 不等于0則跳轉(zhuǎn)至4004f9 主循環(huán)
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 主循環(huán)
26 400510: 8d 50 ff lea -0x1(%rax),%edx # edx = rax - 1(rax的低32位為eax) 主循環(huán)
27 400513: 89 55 fc mov %edx,-0x4(%rbp) # i = edx 主循環(huán)
28 400516: 85 c0 test %eax,%eax # 等同于(i & i), 如果i不等于0,則結(jié)果也不為0 主循環(huán)
29 400518: 75 f3 jne 40050d <minus1+0x20> # 不等于0則跳轉(zhuǎn)至40050d 主循環(huán)
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> # 跳轉(zhuǎn)至400527
34 400523: 83 6d fc 01 subl $0x1,-0x4(%rbp) # i = i - 1 主循環(huán)
35 400527: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) # i與0進(jìn)行比較 主循環(huán)
36 40052b: 75 f6 jne 400523 <minus1+0x36> # 比較結(jié)果不等于0則跳轉(zhuǎn)至400523 主循環(huán)
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 主循環(huán)
49 40053e: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) # i與0比較 主循環(huán)
50 400542: 75 f6 jne 40053a <minus+0xb> # 比較結(jié)果不等于0則跳轉(zhuǎn)至40053a 主循環(huán)
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 主循環(huán)
60 40054f: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) # i與0比較 主循環(huán)
61 400553: 75 f6 jne 40054b <minus+0x1c> # 比較結(jié)果不等于0則跳轉(zhuǎn)至40054b 主循環(huán)
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> # 跳轉(zhuǎn)至400562
66 40055e: 83 6d fc 01 subl $0x1,-0x4(%rbp) # i = i - 1 主循環(huán)
67 400562: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) # i與0比較 主循環(huán)
68 400566: 75 f6 jne 40055e <minus+0x2f> # 比較結(jié)果不等于0則跳轉(zhuǎn)至40055e 主循環(huán)
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 主循環(huán)
82 400579: 8d 50 01 lea 0x1(%rax),%edx # edx = rax + 1(rax的低32位為eax) 主循環(huán)
83 40057c: 89 55 fc mov %edx,-0x4(%rbp) # i = edx 主循環(huán)
84 40057f: 83 f8 09 cmp $0x9,%eax # eax與9比較 主循環(huán)
85 400582: 7e f2 jle 400576 <plus1+0xc> # 比較結(jié)果不成立則跳轉(zhuǎn)至400576 主循環(huán)
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 主循環(huán)
95 40058e: 8d 50 01 lea 0x1(%rax),%edx # edx = rax + 1(rax的低32位為eax) 主循環(huán)
96 400591: 89 55 fc mov %edx,-0x4(%rbp) # i = edx 主循環(huán)
97 400594: 83 f8 09 cmp $0x9,%eax # eax與9比較 主循環(huán)
98 400597: 7e f2 jle 40058b <plus1+0x21> # 比較結(jié)果不成立則跳轉(zhuǎn)至40058b 主循環(huán)
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> # 跳轉(zhuǎn)至4005a6
103 4005a2: 83 45 fc 01 addl $0x1,-0x4(%rbp) # i = i + 1 主循環(huán)
104 4005a6: 83 7d fc 09 cmpl $0x9,-0x4(%rbp) # i與9比較 主循環(huán)
105 4005aa: 7e f6 jle 4005a2 <plus1+0x38> # 比較結(jié)果不成立則跳轉(zhuǎn)至4005a2 主循環(huán)
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 主循環(huán)
118 4005bd: 83 7d fc 09 cmpl $0x9,-0x4(%rbp) # i與9比較 主循環(huán)
119 4005c1: 7e f6 jle 4005b9 <plus+0xb> # 比較結(jié)果不成立則跳轉(zhuǎn)至4005b9 主循環(huán)
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 主循環(huán)
129 4005ce: 83 7d fc 09 cmpl $0x9,-0x4(%rbp) # i與9比較 主循環(huán)
130 4005d2: 7e f6 jle 4005ca <plus+0x1c> # 比較結(jié)果不成立則跳轉(zhuǎn)至4005b9 主循環(huán)
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> # 跳轉(zhuǎn)至4005e1
135 4005dd: 83 45 fc 01 addl $0x1,-0x4(%rbp) # i = i + 1 主循環(huán)
136 4005e1: 83 7d fc 09 cmpl $0x9,-0x4(%rbp) # i與9比較 主循環(huán)
137 4005e5: 7e f6 jle 4005dd <plus+0x2f> # 比較結(jié)果不成立則跳轉(zhuǎn)至4005dd 主循環(huán)
138 ;
139 }
可以從匯編代碼得出如下表格
| while主循環(huán)語(yǔ)句數(shù) |
do...while主循環(huán)語(yǔ)句數(shù) |
for主循環(huán)語(yǔ)句數(shù) | |
| i-- | 5 | 5 | 3 |
| --i | 3 | 3 | 3 |
| i++ | 5 | 5 | 3 |
| ++i | 3 | 3 | 3 |
小結(jié)
可以從表中得出結(jié)論:循環(huán)效率最高也需要執(zhí)行3條匯編語(yǔ)句,而最慢需要5條匯編語(yǔ)句,使用i--和i++進(jìn)行循環(huán)控制時(shí),不同的循環(huán)結(jié)構(gòu)所對(duì)應(yīng)的匯編代碼量不同,最少的為for循環(huán),只需要3條匯編指令,最多的為while循環(huán),需要5條匯編指令,而當(dāng)使用--i和++i進(jìn)行循環(huán)控制時(shí),無論哪一種循環(huán)結(jié)構(gòu)執(zhí)行效率都一樣是最優(yōu)的,都只需要3條代碼,而無論使用i--,--i,i++,++i中哪一種,for循環(huán)的效率應(yīng)該是最高的,都只用了3條匯編代碼。
總結(jié)
以上是生活随笔為你收集整理的关于for,while,dowhile效率测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【ZZ】大数据架构师基础:hadoop家
- 下一篇: (转)java redis使用之利用je