[VB] if 判断语句 和 If、IIf函数的比较

 1 Module Module1
 2     Sub Main()
 3         Dim i As Integer = 1
 4         Dim s1 As String = "我是真的"
 5         Dim s2 As String = "我不是真的"
 6         Dim s3 As String
 7         Dim mx As Integer = 1000000000
 8         Dim start As DateTime
 9 
10         For iii As Integer = 0 To 9
11             start = DateTime.Now
12             For ii As Integer = 0 To mx
13                 If i = 0 Then
14                     s3 = s1
15                 Else
16                     s3 = s2
17                 End If
18             Next
19             Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
20 
21             start = DateTime.Now
22             For ii As Integer = 0 To mx
23                 s3 = If(i = 0, s1, s2)
24             Next
25             Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
26 
27             start = DateTime.Now
28             For ii As Integer = 0 To mx
29                 s3 = IIf(i = 0, s1, s2)
30             Next
31             Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
32 
33             Console.WriteLine("--------------------------------")
34         Next
35     End Sub
36 End Module

执行结果:

2628.1503
2377.1359
6495.3716
--------------------------------
2602.1488
2390.1367
6535.3738
--------------------------------
2579.1475
2414.1381
6532.3736
--------------------------------
2651.1516
2405.1376
6627.3791
--------------------------------
2641.151
2390.1367
6538.374
--------------------------------
2619.1498
2398.1371
6656.3807
--------------------------------
2716.1554
2441.1396
6574.3761
--------------------------------
2623.15
2451.1402
6618.3786
--------------------------------
2650.1516
2409.1378
6550.3747
--------------------------------
2669.1527
2425.1387
6683.3823
--------------------------------

看结果很明显,效率上:If-Else 略大于 If(Express,SelectValue1,SelectValue2) 大于 IIf(Express,SelectValue1,SelectValue2)

这是为什么呢?

 先看全部的IL(当然也可以略去不看,下面我已经将重要片段给截取出来做了比较,提示:本题中大部分指令已在本文结尾处做了注释)

  1 --- D:MoontestConsoleApplication1Module1.vb ---------------------------------
  2         Dim i As Integer = 1
  3 00000000  push        ebp 
  4 00000001  mov         ebp,esp 
  5 00000003  push        edi 
  6 00000004  push        esi 
  7 00000005  sub         esp,108h 
  8 0000000b  lea         edi,[ebp+FFFFFEF0h] 
  9 00000011  mov         ecx,40h 
 10 00000016  xor         eax,eax 
 11 00000018  rep stos    dword ptr es:[edi] 
 12 0000001a  cmp         dword ptr ds:[004B1538h],0 
 13 00000021  je          00000028 
 14 00000023  call        682F477C 
 15 00000028  xor         edx,edx 
 16 0000002a  mov         dword ptr [ebp+FFFFFF00h],edx 
 17 00000030  xor         edx,edx 
 18 00000032  mov         dword ptr [ebp+FFFFFF04h],edx 
 19 00000038  xor         edx,edx 
 20 0000003a  mov         dword ptr [ebp+FFFFFEFCh],edx 
 21 00000040  xor         edx,edx 
 22 00000042  mov         dword ptr [ebp-10h],edx 
 23 00000045  xor         edx,edx 
 24 00000047  mov         dword ptr [ebp-0Ch],edx 
 25 0000004a  xor         edx,edx 
 26 0000004c  mov         dword ptr [ebp-24h],edx 
 27 0000004f  xor         edx,edx 
 28 00000051  mov         dword ptr [ebp-20h],edx 
 29 00000054  xor         edx,edx 
 30 00000056  mov         dword ptr [ebp-1Ch],edx 
 31 00000059  xor         edx,edx 
 32 0000005b  mov         dword ptr [ebp+FFFFFF6Ch],edx 
 33 00000061  xor         edx,edx 
 34 00000063  mov         dword ptr [ebp+FFFFFF68h],edx 
 35 00000069  xor         edx,edx 
 36 0000006b  mov         dword ptr [ebp-28h],edx 
 37 0000006e  mov         dword ptr [ebp-0Ch],1 
 38         Dim s1 As String = "我是真的"
 39 00000075  mov         eax,dword ptr ds:[033C2194h] 
 40 0000007b  mov         dword ptr [ebp+FFFFFF04h],eax 
 41         Dim s2 As String = "我不是真的"
 42 00000081  mov         eax,dword ptr ds:[033C2198h] 
 43 00000087  mov         dword ptr [ebp+FFFFFF00h],eax 
 44         Dim s3 As String
 45         Dim mx As Integer = 1000000000
 46 0000008d  mov         dword ptr [ebp-10h],3B9ACA00h 
 47         Dim start As DateTime
 48 
 49         'For iii As Integer = 0 To 9
 50         start = DateTime.Now
 51 00000094  lea         ecx,[ebp+FFFFFF60h] 
 52 0000009a  call        6678EAC8 
 53 0000009f  lea         edi,[ebp-18h] 
 54 000000a2  lea         esi,[ebp+FFFFFF60h] 
 55 000000a8  movq        xmm0,mmword ptr [esi] 
 56 000000ac  movq        mmword ptr [edi],xmm0 
 57         For ii As Integer = 0 To mx
 58 000000b0  mov         eax,dword ptr [ebp-10h] 
 59 000000b3  mov         dword ptr [ebp-28h],eax 
 60 000000b6  xor         edx,edx 
 61 000000b8  mov         dword ptr [ebp-1Ch],edx 
 62 000000bb  nop 
 63 000000bc  jmp         000000EA 
 64             If i = 0 Then
 65 000000be  cmp         dword ptr [ebp-0Ch],0 
 66 000000c2  jne         000000D3 
 67                 s3 = s1
 68 000000c4  mov         eax,dword ptr [ebp+FFFFFF04h] 
 69 000000ca  mov         dword ptr [ebp+FFFFFEFCh],eax 
 70 000000d0  nop 
 71 000000d1  jmp         000000DF 
 72             Else
 73                 s3 = s2
 74 000000d3  mov         eax,dword ptr [ebp+FFFFFF00h] 
 75 000000d9  mov         dword ptr [ebp+FFFFFEFCh],eax 
 76             End If
 77         Next
 78 000000df  add         dword ptr [ebp-1Ch],1 
 79 000000e3  jno         000000EA 
 80 000000e5  call        682F3C1A 
 81 000000ea  mov         eax,dword ptr [ebp-1Ch] 
 82 000000ed  cmp         eax,dword ptr [ebp-28h] 
 83 000000f0  jle         000000BE 
 84         Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
 85 000000f2  lea         ecx,[ebp+FFFFFF58h] 
 86 000000f8  call        6678EAC8 
 87 000000fd  lea         eax,[ebp+FFFFFF58h] 
 88 00000103  sub         esp,8 
 89 00000106  movq        xmm0,mmword ptr [eax] 
 90 0000010a  movq        mmword ptr [esp],xmm0 
 91 0000010f  lea         eax,[ebp-18h] 
 92 00000112  sub         esp,8 
 93 00000115  movq        xmm0,mmword ptr [eax] 
 94 00000119  movq        mmword ptr [esp],xmm0 
 95 0000011e  lea         ecx,[ebp+FFFFFF50h] 
 96 00000124  call        6678A950 
 97 00000129  lea         edi,[ebp+FFFFFF70h] 
 98 0000012f  lea         esi,[ebp+FFFFFF50h] 
 99 00000135  movq        xmm0,mmword ptr [esi] 
100 00000139  movq        mmword ptr [edi],xmm0 
101 0000013d  lea         ecx,[ebp+FFFFFF70h] 
102 00000143  call        6678DD38 
103 00000148  fstp        qword ptr [ebp+FFFFFF48h] 
104 0000014e  fld         qword ptr [ebp+FFFFFF48h] 
105 00000154  sub         esp,8 
106 00000157  fstp        qword ptr [esp] 
107 0000015a  call        66E72E20 
108 
109         start = DateTime.Now
110 0000015f  lea         ecx,[ebp+FFFFFF40h] 
111 00000165  call        6678EAC8 
112 0000016a  lea         edi,[ebp-18h] 
113 0000016d  lea         esi,[ebp+FFFFFF40h] 
114 00000173  movq        xmm0,mmword ptr [esi] 
115 00000177  movq        mmword ptr [edi],xmm0 
116         For ii As Integer = 0 To mx
117 0000017b  mov         eax,dword ptr [ebp-10h] 
118 0000017e  mov         dword ptr [ebp+FFFFFF6Ch],eax 
119 00000184  xor         edx,edx 
120 00000186  mov         dword ptr [ebp-20h],edx 
121 00000189  nop 
122 0000018a  jmp         000001C4 
123             s3 = If(i = 0, s1, s2)
124 0000018c  cmp         dword ptr [ebp-0Ch],0 
125 00000190  je          000001A1 
126 00000192  nop 
127 00000193  mov         eax,dword ptr [ebp+FFFFFF00h] 
128 00000199  mov         dword ptr [ebp+FFFFFEF8h],eax 
129 0000019f  jmp         000001AD 
130 000001a1  mov         eax,dword ptr [ebp+FFFFFF04h] 
131 000001a7  mov         dword ptr [ebp+FFFFFEF8h],eax 
132 000001ad  mov         eax,dword ptr [ebp+FFFFFEF8h] 
133 000001b3  mov         dword ptr [ebp+FFFFFEFCh],eax 
134         Next
135 000001b9  add         dword ptr [ebp-20h],1 
136 000001bd  jno         000001C4 
137 000001bf  call        682F3C1A 
138 000001c4  mov         eax,dword ptr [ebp-20h] 
139 000001c7  cmp         eax,dword ptr [ebp+FFFFFF6Ch] 
140 000001cd  jle         0000018C 
141         Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
142 000001cf  lea         ecx,[ebp+FFFFFF38h] 
143 000001d5  call        6678EAC8 
144 000001da  lea         eax,[ebp+FFFFFF38h] 
145 000001e0  sub         esp,8 
146 000001e3  movq        xmm0,mmword ptr [eax] 
147 000001e7  movq        mmword ptr [esp],xmm0 
148 000001ec  lea         eax,[ebp-18h] 
149 000001ef  sub         esp,8 
150 000001f2  movq        xmm0,mmword ptr [eax] 
151 000001f6  movq        mmword ptr [esp],xmm0 
152 000001fb  lea         ecx,[ebp+FFFFFF30h] 
153 00000201  call        6678A950 
154 00000206  lea         edi,[ebp-30h] 
155 00000209  lea         esi,[ebp+FFFFFF30h] 
156 0000020f  movq        xmm0,mmword ptr [esi] 
157 00000213  movq        mmword ptr [edi],xmm0 
158 00000217  lea         ecx,[ebp-30h] 
159 0000021a  call        6678DD38 
160 0000021f  fstp        qword ptr [ebp+FFFFFF28h] 
161 00000225  fld         qword ptr [ebp+FFFFFF28h] 
162 0000022b  sub         esp,8 
163 0000022e  fstp        qword ptr [esp] 
164 00000231  call        66E72E20 
165 
166         start = DateTime.Now
167 00000236  lea         ecx,[ebp+FFFFFF20h] 
168 0000023c  call        6678EAC8 
169 00000241  lea         edi,[ebp-18h] 
170 00000244  lea         esi,[ebp+FFFFFF20h] 
171 0000024a  movq        xmm0,mmword ptr [esi] 
172 0000024e  movq        mmword ptr [edi],xmm0 
173         For ii As Integer = 0 To mx
174 00000252  mov         eax,dword ptr [ebp-10h] 
175 00000255  mov         dword ptr [ebp+FFFFFF68h],eax 
176 0000025b  xor         edx,edx 
177 0000025d  mov         dword ptr [ebp-24h],edx 
178 00000260  nop 
179 00000261  jmp         000002AC 
180             s3 = IIf(i = 0, s1, s2)
181 00000263  push        dword ptr [ebp+FFFFFF00h] 
182 00000269  cmp         dword ptr [ebp-0Ch],0 
183 0000026d  sete        cl 
184 00000270  movzx       ecx,cl 
185 00000273  mov         edx,dword ptr [ebp+FFFFFF04h] 
186 00000279  call        55FD3238 
187 0000027e  mov         dword ptr [ebp+FFFFFEF4h],eax 
188 00000284  mov         ecx,dword ptr [ebp+FFFFFEF4h] 
189 0000028a  call        55FAFAA0 
190 0000028f  mov         dword ptr [ebp+FFFFFEF0h],eax 
191 00000295  mov         eax,dword ptr [ebp+FFFFFEF0h] 
192 0000029b  mov         dword ptr [ebp+FFFFFEFCh],eax 
193         Next
194 000002a1  add         dword ptr [ebp-24h],1 
195 000002a5  jno         000002AC 
196 000002a7  call        682F3C1A 
197 000002ac  mov         eax,dword ptr [ebp-24h] 
198 000002af  cmp         eax,dword ptr [ebp+FFFFFF68h] 
199 000002b5  jle         00000263 
200         Console.WriteLine((DateTime.Now - start).TotalMilliseconds)
201 000002b7  lea         ecx,[ebp+FFFFFF18h] 
202 000002bd  call        6678EAC8 
203 000002c2  lea         eax,[ebp+FFFFFF18h] 
204 000002c8  sub         esp,8 
205 000002cb  movq        xmm0,mmword ptr [eax] 
206 000002cf  movq        mmword ptr [esp],xmm0 
207 000002d4  lea         eax,[ebp-18h] 
208 000002d7  sub         esp,8 
209 000002da  movq        xmm0,mmword ptr [eax] 
210 000002de  movq        mmword ptr [esp],xmm0 
211 000002e3  lea         ecx,[ebp+FFFFFF10h] 
212 000002e9  call        6678A950 
213 000002ee  lea         edi,[ebp-30h] 
214 000002f1  lea         esi,[ebp+FFFFFF10h] 
215 000002f7  movq        xmm0,mmword ptr [esi] 
216 000002fb  movq        mmword ptr [edi],xmm0 
217 000002ff  lea         ecx,[ebp-30h] 
218 00000302  call        6678DD38 
219 00000307  fstp        qword ptr [ebp+FFFFFF08h] 
220 0000030d  fld         qword ptr [ebp+FFFFFF08h] 
221 00000313  sub         esp,8 
222 00000316  fstp        qword ptr [esp] 
223 00000319  call        66E72E20 
224 
225         Console.WriteLine("--------------------------------")
226 0000031e  mov         ecx,dword ptr ds:[033C219Ch] 
227 00000324  call        6682AAB8 
228         'Next
229     End Sub
230 00000329  nop 
231 0000032a  lea         esp,[ebp-8] 
232 0000032d  pop         esi 
233 0000032e  pop         edi 
234 0000032f  pop         ebp 
235 00000330  ret 
转化IL 

对比不同点(If-Else || If(Express,SelecetValue1,SelectValue2) || IIf(Express,SelecetValue1,SelectValue2):

红色方框内的行数,影响到运行时间。 

看后我们发现,If-Else 与 If(Express,SelectValue1,SelectValue2) 实现的IL代码几乎完全一样 If(Express,SelectValue1,SelectValue2) IL中虽然多执行了两步操作,但是仔细看你会发现只不过是进行了多余操作)。

那么我们在执行过程时,为什么If-Else的时间略比If(Express,SelectValue1,SelectValue2)的时间大呢? 那是因为If-Else里面多了nop 指令,如果没它,If-Else 比 If(Express,SelectValue1,SelectValue2) 快。

至于 IIf(Express,SelectValue1,SelectValue2)  那是因为里面多进行了两步call 指令,这两个过程是执行内存别处指令,执行完之后再跳转回执行下一条指令(应该是Iff有很多判断,比较复杂吧?!我没用有仔细查看内存)。

帮助信息(参阅 IL指令汇总):

dword ptr[ebp-0Ch]  :  取内存地址ebp-0Ch中的数据,地址ebp-0Ch中保存的是Integer i

cmp  dword ptr[ebp-0Ch]  ,   0   : 比较 i 和 0 【对两数进行相减,进行比较,不将两数的差放入第一个操作数,影响标志寄存器,个人认为应该影响零标识(ZF)和符号标识(SF),具体的请搜索下标志寄存器】

jne  000000d3  :    ZF=0 , 跳转至  000000d3  (ZF是零标识,若运算结果为零则ZF=1,否则ZF=0)

mov eax , dword ptr[ebp+FFFFFF04h] :  将操作数dword ptr[ebp+FFFFFF04h]送入eax寄存器 , 这个是什么玩意呢?  此句中的dword ptr[ebp+FFFFFF04h] 指向我们自定义的字符串

jmp 000000DF : 强制跳转至 000000DF 

je 000001A1 :  ZF=1,跳转至  000001A1 (参考jne)

sete cl : 取标志寄存器中ZF的值, 放到cl中

call  55EC3238  :  调至55EC3238执行指令

movzx  ecx , cl : ecx 高位8~32位强制为0

nop :本指令不产生任何结果,仅消耗几个时钟周期的时间,接着执行后续指令,常用于程序的延时等

原文地址:https://www.cnblogs.com/preacher/p/4191972.html