• [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 :本指令不产生任何结果,仅消耗几个时钟周期的时间,接着执行后续指令,常用于程序的延时等

  • 相关阅读:
    C# 字段 属性 方法 三霸主齐上阵
    C# 项目之总结,浓缩才是精华
    C# 语法 重中之重
    岁月流逝,C#成为我们IT精英永恒不变的经典
    pv:快餐厅4类职员正确并发运行的程序——用pv实现有向图的前驱关系哦!
    pv错题:用pv操作实现旅客,汽车之间的同步关系——北航2018考研计算机!!!!!!!!我还很不熟练,奋斗吧少年!!!!!!
    windows 的 DMA
    pv打卡:生产者消费者问题扩展——>南航2002pv习题哦
    冷门的OS知识:中断——这个我多大熟练qwq!
    Unix混合索引结构_文件系统_文件的组织_文件的物理结构_多级索引文件——>相关的小计算题!!!!!!重点重点重点!!!!!!
  • 原文地址:https://www.cnblogs.com/preacher/p/4191972.html
Copyright © 2020-2023  润新知