A coworker and I have differing opinions on If
statements and their performance. My view is that If...ElseIf
statements should be used. His view is that he doesn't believe in ElseIf
, and writes everything with nested If
statements.
Let's assume that a case statement cannot be used in this situation. What I am wondering is how efficiently code will be executed using nested If..Else
statements versus using If...ElseIf
statements. I know that code readability is a factor, but that shouldn't' affect performance.
Lets look at the following examples.
Using If Else:
If () then
'Do something'
Else
If () then
'Do something'
Else
If () then
'Do something'
Else
If () then
'Do something'
Else
'Do something else'
End If
End If
End If
End If
Using ElseIf:
If () then
'Do something'
ElseIf () then
'Do something'
ElseIf () then
'Do something'
ElseIf () then
'Do something'
Else
'Do something else'
End If
I know this is a small scale example, but lets say blocks like this are used heavily throughout the application.
Are there any performance differences between the two code sections, or would they perform almost identically once the application is compiled?
####UPDATE#####
I created a program to test running through the functions x number of times.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i As Integer = 0 To 1000
Run()
Next
End Sub
Sub Run()
Dim Time1Start As Integer = 0
Dim Time1End As Integer = 0
Dim Time2Start As Integer = 0
Dim Time2End As Integer = 0
Time2Start = CInt(DateTime.Now.ToString("fff"))
runElse()
Time2End = CInt(DateTime.Now.ToString("fff"))
Time1Start = CInt(DateTime.Now.ToString("fff"))
runElseIf()
Time1End = CInt(DateTime.Now.ToString("fff"))
TextBox1.Text += If(Time1End < Time1Start, Time1End + (1000 - Time1Start), Time1End - Time1Start) & vbTab & If(Time2End < Time2Start, Time2End + (1000 - Time2Start), Time2End - Time2Start) & vbCrLf
End Sub
Sub runElseIf()
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
If sleep(10) Then
'Do something'
Else
'Do something else'
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End Sub
Sub runElse()
If sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
ElseIf sleep(10) Then
'Do something'
Else
'Do something else'
End If
End Sub
Function sleep(ByVal ms As Integer) As Integer
System.Threading.Thread.Sleep(ms)
Return False
End Function
End Class
I ran the program and here are my results:
500 Loops Average - ElseIf: 108.248ms If Else: 106.507ms
1000 Loops Average - ElseIf: 107.747ms If Else: 107.451ms (Else If running first)
1000 Loops Average - ElseIf: 107.683ms If Else: 107.076ms (ElseIf running first)
Perhaps with a larger data set the numbers would change, but out of those 3 trials it actually appears that the If Else
is outperforming the ElseIf
statements.
I've decompiled the two and it seem to be generating the same code (using ildasm). This is a very simple If statment, might get different result for different If. I would suggest you do the same with your code and see.
Module Module1
Sub Main()
Dim a As Integer
Dim i As Integer = 1
If i = 1 Then
a = 9
ElseIf i = 2 Then
a = 8
ElseIf i = 3 Then
a = 7
Else
a = 6
End If
End Sub
End Module
.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 30 (0x1e)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 i)
IL_0000: ldc.i4.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: ldc.i4.1
IL_0004: bne.un.s IL_000b
IL_0006: ldc.i4.s 9
IL_0008: stloc.0
IL_0009: br.s IL_001d
IL_000b: ldloc.1
IL_000c: ldc.i4.2
IL_000d: bne.un.s IL_0013
IL_000f: ldc.i4.8
IL_0010: stloc.0
IL_0011: br.s IL_001d
IL_0013: ldloc.1
IL_0014: ldc.i4.3
IL_0015: bne.un.s IL_001b
IL_0017: ldc.i4.7
IL_0018: stloc.0
IL_0019: br.s IL_001d
IL_001b: ldc.i4.6
IL_001c: stloc.0
IL_001d: ret
} // end of method Module1::Main
And the other one
Module Module1
Sub Main()
Dim a As Integer
Dim i As Integer = 1
If i = 1 Then
a = 9
Else
If i = 2 Then
a = 8
Else
If i = 3 Then
a = 7
Else
a = 6
End If
End If
End If
End Sub
End Module
.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 30 (0x1e)
.maxstack 2
.locals init ([0] int32 a,
[1] int32 i)
IL_0000: ldc.i4.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: ldc.i4.1
IL_0004: bne.un.s IL_000b
IL_0006: ldc.i4.s 9
IL_0008: stloc.0
IL_0009: br.s IL_001d
IL_000b: ldloc.1
IL_000c: ldc.i4.2
IL_000d: bne.un.s IL_0013
IL_000f: ldc.i4.8
IL_0010: stloc.0
IL_0011: br.s IL_001d
IL_0013: ldloc.1
IL_0014: ldc.i4.3
IL_0015: bne.un.s IL_001b
IL_0017: ldc.i4.7
IL_0018: stloc.0
IL_0019: br.s IL_001d
IL_001b: ldc.i4.6
IL_001c: stloc.0
IL_001d: ret
} // end of method Module1::Main
I would suggest to use the one that is easier to read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With