If a Then If b Then If c Then If d Then If e Then x = "Passed" Else x = "Failed"
That is some horrendous code right there, and it doesn't do what you think it does either: the 3 "methods" you're showing are NOT equivalent. If we expand #3...
If a Then
If b Then
If c Then
If d Then
If e Then
x = "Passed"
Else
x = "Failed"
End If
End If
End If
End If
End If
...we see much more clearly that the only way to get x = "Failed"
is to have all but e
be True
- x
remains unassigned in every single other case.
It doesn't matter which method is the fastest, if the fastest method doesn't work as it should.
In fact, it doesn't matter which method is the fastest, if reading that code is deceptive and looks like it should do something, but when you actually stop and read what's going on, you realize it's doing something else.
Write code that's correct first. Then make that code obviously correct. Then make it more efficient if it needs to be made more efficient: the vast majority of the time, if your code has a performance bottleneck, it's not going to be in places like this.
"Method 2" will wrongly output "Passed" if a
and b
are both False
and everything else is True
.
"Method 1" is the only code you've got that will consistently output "Passed" when all conditions are true, and "Failed" when one of the conditions is false.
Don't try to write clever code. Write code that works, and then refactor as needed.
What's [slightly] inefficient about #1 is that it evaluates all conditions, even if a
is False
- in languages such as C# or Java, the condition would "short-circuit" and the rest of the expression wouldn't be evaluated. In VB.NET, the AndAlso
short-circuiting operator would do the same.
If profiling code execution reveals that evaluating these conditionals is a performance bottleneck, then the first step is to take #1 and nest the conditions.
x = "Failed"
If a Then
If b Then
If c Then
If d Then
If e Then
x = "Passed"
End If
End If
End If
End If
End If
Now we still get correct results, and only evaluate all conditions if we have to. Problem is, that's arrow code, and it's annoyingly ugly.
So what we do is, we write a function whose role is abstract away the iteration a bunch of conditions, and bail out as soon as one of them is False
:
Public Function All(ParamArray values() As Variant) As Boolean
Dim i As Long
For i = LBound(values) To UBound(values)
If Not CBool(values(i)) Then Exit Function
Next
All = True
End Function
And now we get performant short-circuiting logic* and readability:
x = IIf(All(a, b, c, d, e), "Passed", "Failed")
* Assuming a
, b
, c
, d
, and e
are all values and not expressions. Expressions would all have to be evaluated in order for their results to be passed as arguments to the function.