Switch Case, Select Active, or If Else If?
Spire_Jeff
Posts: 1,917
Here are some results from my benchmark code for the various methods. Initial testing is being performed on switching based on a single character. If I have some time or inspiration, I will try the test with strings and also with plain integers. Here are the test parameters:
- 4 Different methods are being tested. They are Switch Case, Select Active, If Else If, and multiple If statements.
- The method is passed a data array filled with characters. The method then sets the indexed value of nInfo to an integer based on the character at the corresponding indexed position of the data array. The function uses a for loop to parse the entire data array.
- Each test timer is started immediately before the method is called, and ended immediately after the method returns.
- Each method is tested 4 ways. First is with a FUNCTION CALL using a data array filled only with 'A'. Second is with a FUNCTION CALL using a data array filled only with 'Z'. Third is with a FUNCTION CALL using a data array filled with random characters from 'A' to 'Z'. Last is a DEFINE_CALL called using the same random array from test 3.
This is what I think should logically happen:
- The difference between a DEFINE_FUNCTION and a DEFINE_CALL should be negligible. This is mainly because the function/call is only being called once for the test. (I will setup another test specifically to test this aspect after these tests finish)
- The first three test methods should be fastest when dealing with an array filled only with 'A', slowest with an array filled with only 'Z', and somewhere in between for the random characters.
- The fourth test (multiple If statements) Should be the same speed regardless of the array used.
And, here are the results:
It seems that Switch Case wins on a single character. Select Active and If Else If are almost identical. The big surprise to me is that multiple If statements are slower when the data coming to them is random. I thought for sure that each if() statement would need to be evaluated and since one of them is always evaluating to true, it should take the same amount of time for each run through regardless of the result.
The timing on the first three methods follows the patterns I was thinking they should.
If you would like a copy of the code to play with, let me know and I'll post it here.
I am going to check the differences between a function and a call real quick
Jeff
- 4 Different methods are being tested. They are Switch Case, Select Active, If Else If, and multiple If statements.
- The method is passed a data array filled with characters. The method then sets the indexed value of nInfo to an integer based on the character at the corresponding indexed position of the data array. The function uses a for loop to parse the entire data array.
- Each test timer is started immediately before the method is called, and ended immediately after the method returns.
- Each method is tested 4 ways. First is with a FUNCTION CALL using a data array filled only with 'A'. Second is with a FUNCTION CALL using a data array filled only with 'Z'. Third is with a FUNCTION CALL using a data array filled with random characters from 'A' to 'Z'. Last is a DEFINE_CALL called using the same random array from test 3.
This is what I think should logically happen:
- The difference between a DEFINE_FUNCTION and a DEFINE_CALL should be negligible. This is mainly because the function/call is only being called once for the test. (I will setup another test specifically to test this aspect after these tests finish)
- The first three test methods should be fastest when dealing with an array filled only with 'A', slowest with an array filled with only 'Z', and somewhere in between for the random characters.
- The fourth test (multiple If statements) Should be the same speed regardless of the array used.
And, here are the results:
Line 1 (18:33:27):: ********************************************************* Line 2 (18:33:27):: * TEST 1 REPORT: SwitchCase "A" Function Line 3 (18:33:27):: * Most recent 5 runs: Line 4 (18:33:27):: * 1: 2089ms Line 5 (18:33:27):: * 2: 2096ms Line 6 (18:33:27):: * 3: 2090ms Line 7 (18:33:27):: * 4: 2088ms Line 8 (18:33:27):: * 5: 2097ms Line 9 (18:33:27):: *---------------------------------------------------------- Line 10 (18:33:27):: * Average run time: 2091ms - over 6 tests Line 11 (18:33:27):: ********************************************************* Line 12 (18:33:27):: ********************************************************* Line 13 (18:33:27):: * TEST 2 REPORT: SwitchCase "Z" Function Line 14 (18:33:27):: * Most recent 5 runs: Line 15 (18:33:27):: * 1: 2258ms Line 16 (18:33:27):: * 2: 2267ms Line 17 (18:33:27):: * 3: 2258ms Line 18 (18:33:27):: * 4: 2259ms Line 19 (18:33:27):: * 5: 2264ms Line 20 (18:33:27):: *---------------------------------------------------------- Line 21 (18:33:27):: * Average run time: 2259ms - over 6 tests Line 22 (18:33:27):: ********************************************************* Line 23 (18:33:27):: ********************************************************* Line 24 (18:33:27):: * TEST 3 REPORT: SwitchCase "Random" Function Line 25 (18:33:27):: * Most recent 5 runs: Line 26 (18:33:27):: * 1: 2173ms Line 27 (18:33:27):: * 2: 2177ms Line 28 (18:33:27):: * 3: 2174ms Line 29 (18:33:27):: * 4: 2173ms Line 30 (18:33:27):: * 5: 2181ms Line 31 (18:33:27):: *---------------------------------------------------------- Line 32 (18:33:27):: * Average run time: 2173ms - over 6 tests Line 33 (18:33:27):: ********************************************************* Line 34 (18:33:27):: ********************************************************* Line 35 (18:33:27):: * TEST 4 REPORT: SwitchCase "Random" Call Line 36 (18:33:27):: * Most recent 5 runs: Line 37 (18:33:27):: * 1: 2202ms Line 38 (18:33:27):: * 2: 2208ms Line 39 (18:33:27):: * 3: 2204ms Line 40 (18:33:27):: * 4: 2208ms Line 41 (18:33:27):: * 5: 2210ms Line 42 (18:33:27):: *---------------------------------------------------------- Line 43 (18:33:27):: * Average run time: 2205ms - over 6 tests Line 44 (18:33:27):: ********************************************************* Line 45 (18:33:27):: ********************************************************* Line 46 (18:33:27):: * TEST 5 REPORT: SelectActive "A" Function Line 47 (18:33:27):: * Most recent 5 runs: Line 48 (18:33:27):: * 1: 2381ms Line 49 (18:33:27):: * 2: 2381ms Line 50 (18:33:27):: * 3: 2382ms Line 51 (18:33:27):: * 4: 2379ms Line 52 (18:33:27):: * 5: 2384ms Line 53 (18:33:27):: *---------------------------------------------------------- Line 54 (18:33:27):: * Average run time: 2381ms - over 6 tests Line 55 (18:33:27):: ********************************************************* Line 56 (18:33:27):: ********************************************************* Line 57 (18:33:27):: * TEST 6 REPORT: SelectActive "Z" Function Line 58 (18:33:27):: * Most recent 5 runs: Line 59 (18:33:27):: * 1: 2612ms Line 60 (18:33:27):: * 2: 2614ms Line 61 (18:33:27):: * 3: 2613ms Line 62 (18:33:27):: * 4: 2614ms Line 63 (18:33:27):: * 5: 2618ms Line 64 (18:33:27):: *---------------------------------------------------------- Line 65 (18:33:27):: * Average run time: 2613ms - over 6 tests Line 66 (18:33:27):: ********************************************************* Line 67 (18:33:27):: ********************************************************* Line 68 (18:33:27):: * TEST 7 REPORT: SelectActive "Random" Function Line 69 (18:33:27):: * Most recent 5 runs: Line 70 (18:33:27):: * 1: 2596ms Line 71 (18:33:27):: * 2: 2595ms Line 72 (18:33:27):: * 3: 2596ms Line 73 (18:33:27):: * 4: 2594ms Line 74 (18:33:27):: * 5: 2599ms Line 75 (18:33:27):: *---------------------------------------------------------- Line 76 (18:33:27):: * Average run time: 2595ms - over 6 tests Line 77 (18:33:27):: ********************************************************* Line 78 (18:33:27):: ********************************************************* Line 79 (18:33:27):: * TEST 8 REPORT: SelectActive "Random" Call Line 80 (18:33:27):: * Most recent 5 runs: Line 81 (18:33:27):: * 1: 2570ms Line 82 (18:33:27):: * 2: 2571ms Line 83 (18:33:27):: * 3: 2571ms Line 84 (18:33:27):: * 4: 2571ms Line 85 (18:33:27):: * 5: 2572ms Line 86 (18:33:27):: *---------------------------------------------------------- Line 87 (18:33:27):: * Average run time: 2570ms - over 6 tests Line 88 (18:33:27):: ********************************************************* Line 89 (18:33:27):: ********************************************************* Line 90 (18:33:27):: * TEST 9 REPORT: IfElseIf "A" Function Line 91 (18:33:27):: * Most recent 5 runs: Line 92 (18:33:27):: * 1: 2373ms Line 93 (18:33:27):: * 2: 2372ms Line 94 (18:33:27):: * 3: 2373ms Line 95 (18:33:27):: * 4: 2373ms Line 96 (18:33:27):: * 5: 2378ms Line 97 (18:33:27):: *---------------------------------------------------------- Line 98 (18:33:27):: * Average run time: 2373ms - over 6 tests Line 99 (18:33:27):: ********************************************************* Line 100 (18:33:27):: ********************************************************* Line 101 (18:33:27):: * TEST 10 REPORT: IfElseIf "Z" Function Line 102 (18:33:27):: * Most recent 5 runs: Line 103 (18:33:27):: * 1: 2606ms Line 104 (18:33:27):: * 2: 2606ms Line 105 (18:33:27):: * 3: 2607ms Line 106 (18:33:27):: * 4: 2606ms Line 107 (18:33:27):: * 5: 2611ms Line 108 (18:33:27):: *---------------------------------------------------------- Line 109 (18:33:27):: * Average run time: 2606ms - over 6 tests Line 110 (18:33:27):: ********************************************************* Line 111 (18:33:27):: ********************************************************* Line 112 (18:33:27):: * TEST 11 REPORT: IfElseIf "Random" Function Line 113 (18:33:27):: * Most recent 5 runs: Line 114 (18:33:27):: * 1: 2581ms Line 115 (18:33:27):: * 2: 2580ms Line 116 (18:33:27):: * 3: 2581ms Line 117 (18:33:27):: * 4: 2580ms Line 118 (18:33:27):: * 5: 2587ms Line 119 (18:33:27):: *---------------------------------------------------------- Line 120 (18:33:27):: * Average run time: 2581ms - over 6 tests Line 121 (18:33:27):: ********************************************************* Line 122 (18:33:27):: ********************************************************* Line 123 (18:33:27):: * TEST 12 REPORT: IfElseIf "Random" Call Line 124 (18:33:27):: * Most recent 5 runs: Line 125 (18:33:27):: * 1: 2588ms Line 126 (18:33:27):: * 2: 2587ms Line 127 (18:33:27):: * 3: 2586ms Line 128 (18:33:27):: * 4: 2586ms Line 129 (18:33:27):: * 5: 2586ms Line 130 (18:33:27):: *---------------------------------------------------------- Line 131 (18:33:27):: * Average run time: 2586ms - over 6 tests Line 132 (18:33:27):: ********************************************************* Line 133 (18:33:27):: ********************************************************* Line 134 (18:33:27):: * TEST 13 REPORT: If "A" Function Line 135 (18:33:27):: * Most recent 5 runs: Line 136 (18:33:27):: * 1: 2752ms Line 137 (18:33:27):: * 2: 2754ms Line 138 (18:33:27):: * 3: 2755ms Line 139 (18:33:27):: * 4: 2754ms Line 140 (18:33:27):: * 5: 2755ms Line 141 (18:33:27):: *---------------------------------------------------------- Line 142 (18:33:27):: * Average run time: 2753ms - over 6 tests Line 143 (18:33:27):: ********************************************************* Line 144 (18:33:27):: ********************************************************* Line 145 (18:33:27):: * TEST 14 REPORT: If "Z" Function Line 146 (18:33:27):: * Most recent 5 runs: Line 147 (18:33:27):: * 1: 2752ms Line 148 (18:33:27):: * 2: 2753ms Line 149 (18:33:27):: * 3: 2751ms Line 150 (18:33:27):: * 4: 2753ms Line 151 (18:33:27):: * 5: 2751ms Line 152 (18:33:27):: *---------------------------------------------------------- Line 153 (18:33:27):: * Average run time: 2751ms - over 6 tests Line 154 (18:33:27):: ********************************************************* Line 155 (18:33:27):: ********************************************************* Line 156 (18:33:27):: * TEST 15 REPORT: If "Random" Function Line 157 (18:33:27):: * Most recent 5 runs: Line 158 (18:33:27):: * 1: 2861ms Line 159 (18:33:27):: * 2: 2861ms Line 160 (18:33:27):: * 3: 2862ms Line 161 (18:33:27):: * 4: 2861ms Line 162 (18:33:27):: * 5: 2862ms Line 163 (18:33:27):: *---------------------------------------------------------- Line 164 (18:33:27):: * Average run time: 2861ms - over 6 tests Line 165 (18:33:27):: *********************************************************
It seems that Switch Case wins on a single character. Select Active and If Else If are almost identical. The big surprise to me is that multiple If statements are slower when the data coming to them is random. I thought for sure that each if() statement would need to be evaluated and since one of them is always evaluating to true, it should take the same amount of time for each run through regardless of the result.
The timing on the first three methods follows the patterns I was thinking they should.
If you would like a copy of the code to play with, let me know and I'll post it here.
I am going to check the differences between a function and a call real quick
Jeff
0
Comments
I would agree if I were using a single variable, but I am using an array and setting each element of the array to the letter A. Altho, now that I think about it, maybe it is a matter of the processor caching the code block to be run? I'm thinking if I create an array where I use blocks of the same letter, the time should be close to the same as all one letter.
Back in a few.
Jeff
Because of this, the tests were not run as I expected them to run because after the first 1000 iterations, all of the methods were probably going to the default condition which is the last condition. The new test results seem more inline with what I was expecting.
I think this was what caused the multiple if statements method to vary between the random chars and fixed chars. The last if statement looks like this:
I think the data in the arrays caused the fixed char arrays to fail the first condition in the if statement and as a result, the second condition was never tested because of the AND. This raises some more questions about if the processor is able to stop evaluating a condition as soon as it cannot be true.
Regardless, here are the new results.
As you can see, in a real world situation where data is random, there is little difference between switch..case, select..active, and if..else..if. Interestingly enough, it seems that select..active and ifElseIf are faster than switch..case when the majority of values are the first condition, but slower when the majority of the values are the last condition.
This reinforces my tendency to put conditions I think will occur most often first. Think about a device like a security panel. It would make sense to check for a status/blink message as the first condition, then maybe put zone status messages next, then put fire/burglary messages at the end of the line.
Jeff
Our instructor at PIII last August said that Switch/Case is actually a pretty spendy process. He mad eht statement that they found no significant differences between the methods of conditional searching. Of course, it's a little hard to compare apples to apples.
I myself tend to use them based upon what strength they offer in the search I'm trying to accomplish.
I don't understand how that can be. If you have a switch with 100 cases in a parsing function and 99% of the time your parsing a KLS string for Lutron for example, putting the test for the KLS string in the last case position would obviously be waisting time since 99% of the time it will have to test 99 cases prior to getting to the case which tests for the KLS. It only makes sense to put that in the first case position and something like LOGIN: or login successful should be at the bottom of the switch since those are only tested once upon connection.
Jeff
I'm not sure. It was just a curiosity at the time. I remember back in my old days of computer engineering and processor/compiler design that conditionals are notoriously time consuming. But we have to do them.
As I said, I don't get too involved with how well the engine is running myself. I try to pick the method that makes the most programming sense to me. I'm not against using IF/ELSE if it works out to be the best method. I like to use it when you may have more than one condition be true in a given pass. I cannot remember in Netlinx but in other languages Switch/Case and/or Select Active jump out once a condition is met. There are times when you can get more than one set of data out of a pass by allowing for more than one case to be true.
There are two ways to use the if to accomplish the same thing as a select/active. There is
This method checks every statement all of the time.
Then there is this:
The second way work just like select/active. In java, there is no select/active (that I am aware of), you have to use this method.
As for other languages, in some of them, the switch case statement only jumps out if you include a break command at the end of the case. This is something that I wish NetLinx would allow as sometimes it would be helpful. I do understand that in most situations it is not the desired behavior, and I can understand why they automatically break the case.
Jeff
For those interested, here are the functions used in the test:
Jeff