I have a huge DataTable, and I need go by each row and validate an specific value.
Which method give me more performance, an structure of IF ELSE or SELECT CASE? (I'm focused in the method that offer me the best performance)
IF ELSE (METHOD #1)
For Each vRow In vDTtemp.Rows
If vRow("Item") = "Time" Then
vRow("Result") = "000"
ElseIf vRow("Item") = "DateTime" Then
vRow("Result") = "001"
ElseIf vRow("Item") = "String" Then
vRow("Result") = "002"
Else
vRow("Result") = "N/A"
End If
Next
SELECT CASE (METHOD #2)
For Each vRow In vDTtemp.Rows
Select Case vRow("Item")
Case "Time"
vRow("Result") = "000"
Case "DateTime"
vRow("Result") = "001"
Case "String"
vRow("Result") = "002"
Case Else
vRow("Result") = "N/A"
End Select
Next
Case statement is useful to execute a single case statement from the group of multiple case statements based on the value of a defined expression. By using Select... Case statement in Visual Basic, we can replace the functionality of if…else if statement to provide better readability for the code.
Speed: A switch statement might prove to be faster than ifs provided number of cases are good. If there are only few cases, it might not effect the speed in any case. Prefer switch if the number of cases are more than 5 otherwise, you may use if-else too.
Main Difference between If-else and Switch CaseThe if-else statement is used to choose between two options, but the switch case statement is used to choose between numerous options. If the condition inside the if block is false, the statement inside the else block is executed.
Select Case is a conditional statement, that helps you test a variable for equality against a set of values. Each value is referred to as a case, and a variable that is being switched on should be checked for all the select cases.
It makes no difference, both code styles generate the exact same IL. Something you can see by running the ildasm.exe tool on your compiled assembly.
In general, the VB.NET compiler does make an effort to optimize a Select statement. That will work when it uses a simple value type as the selector and trivial Case statements. The generated code will use a dedicated IL instruction, Opcodes.Switch. Which will be compiled to machine code that uses a lookup table. Very fast.
That however doesn't work when you use a string expression as the selector. Making a lookup table for that one would require the equivalent of a dictionary of delegates. That's too impactful, the compiler cannot do anything but convert each case statement to the equivalent of an If statement. You can however optimize it yourself easily by creating this Dictionary in your code, easy to do since the dictionary key and value are just simple strings. You don't have enough cases and the strings are too short to make this pay off majorly, although it is worth a try. It certainly can compact your code.
I've spent quite a lot of time working on this same problem over the last couple of days and have found one approach which is much faster than the others. I too found that using Select Case on a string variable was equivalent to a series of If/Else If statements, and both were disappointingly slow.
However the following technique has worked very well, and reduced the amount of time by over 50%. Instead of the original code:
For Each vRow In vDTtemp.Rows
Select Case vRow("Item")
Case "Time"
vRow("Result") = "000"
Case "DateTime"
vRow("Result") = "001"
Case "String"
vRow("Result") = "002"
Case Else
vRow("Result") = "N/A"
End Select
Next
Change it around to switch on a simple Boolean, and use the String.Equals method, like this:
For Each vRow In vDTtemp.Rows
'Read out the row value so we only need to access the datarow once
rowValue = vRow("Item")
'Which of these statements is true?
Select Case True
Case rowValue.Equals("Time")
vRow("Result") = "000"
Case rowValue.Equals("DateTime")
vRow("Result") = "001"
Case rowValue.Equals("String")
vRow("Result") = "002"
Case Else
vRow("Result") = "N/A"
End Select
Next
I've had significant improvements by approaching it in this way, in one case reducing my code from 1.3 seconds over a 100,000 iteration loop to 0.5 seconds. If this is in a really frequently-called time-critical section of code, that can make a big difference.
As pointed out in the comments below however, this performs an "Ordinal" comparison of strings, which may not result in the expected behaviour if non-English locales are being used (see the comments for examples).
Adam.
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