What Is Quicker, Switch on String or Elseif on Type

What is quicker, switch on string or elseif on type?

Greg's profile results are great for the exact scenario he covered, but interestingly, the relative costs of the different methods change dramatically when considering a number of different factors including the number of types being compared, and the relative frequency and any patterns in the underlying data.

The simple answer is that nobody can tell you what the performance difference is going to be in your specific scenario, you will need to measure the performance in different ways yourself in your own system to get an accurate answer.

The If/Else chain is an effective approach for a small number of type comparisons, or if you can reliably predict which few types are going to make up the majority of the ones that you see. The potential problem with the approach is that as the number of types increases, the number of comparisons that must be executed increases as well.

if I execute the following:

int value = 25124;
if(value == 0) ...
else if (value == 1) ...
else if (value == 2) ...
...
else if (value == 25124) ...

each of the previous if conditions must be evaluated before the correct block is entered. On the other hand

switch(value) {
case 0:...break;
case 1:...break;
case 2:...break;
...
case 25124:...break;
}

will perform one simple jump to the correct bit of code.

Where it gets more complicated in your example is that your other method uses a switch on strings rather than integers which gets a little more complicated. At a low level, strings can't be switched on in the same way that integer values can so the C# compiler does some magic to make this work for you.

If the switch statement is "small enough" (where the compiler does what it thinks is best automatically) switching on strings generates code that is the same as an if/else chain.

switch(someString) {
case "Foo": DoFoo(); break;
case "Bar": DoBar(); break;
default: DoOther; break;
}

is the same as:

if(someString == "Foo") {
DoFoo();
} else if(someString == "Bar") {
DoBar();
} else {
DoOther();
}

Once the list of items in the dictionary gets "big enough" the compiler will automatically create an internal dictionary that maps from the strings in the switch to an integer index and then a switch based on that index.

It looks something like this (Just imagine more entries than I am going to bother to type)

A static field is defined in a "hidden" location that is associated with the class containing the switch statement of type Dictionary<string, int> and given a mangled name

//Make sure the dictionary is loaded
if(theDictionary == null) {
//This is simplified for clarity, the actual implementation is more complex
// in order to ensure thread safety
theDictionary = new Dictionary<string,int>();
theDictionary["Foo"] = 0;
theDictionary["Bar"] = 1;
}

int switchIndex;
if(theDictionary.TryGetValue(someString, out switchIndex)) {
switch(switchIndex) {
case 0: DoFoo(); break;
case 1: DoBar(); break;
}
} else {
DoOther();
}

In some quick tests that I just ran, the If/Else method is about 3x as fast as the switch for 3 different types (where the types are randomly distributed). At 25 types the switch is faster by a small margin (16%) at 50 types the switch is more than twice as fast.

If you are going to be switching on a large number of types, I would suggest a 3rd method:

private delegate void NodeHandler(ChildNode node);

static Dictionary<RuntimeTypeHandle, NodeHandler> TypeHandleSwitcher = CreateSwitcher();

private static Dictionary<RuntimeTypeHandle, NodeHandler> CreateSwitcher()
{
var ret = new Dictionary<RuntimeTypeHandle, NodeHandler>();

ret[typeof(Bob).TypeHandle] = HandleBob;
ret[typeof(Jill).TypeHandle] = HandleJill;
ret[typeof(Marko).TypeHandle] = HandleMarko;

return ret;
}

void HandleChildNode(ChildNode node)
{
NodeHandler handler;
if (TaskHandleSwitcher.TryGetValue(Type.GetRuntimeType(node), out handler))
{
handler(node);
}
else
{
//Unexpected type...
}
}

This is similar to what Ted Elliot suggested, but the usage of runtime type handles instead of full type objects avoids the overhead of loading the type object through reflection.

Here are some quick timings on my machine:


Testing 3 iterations with 5,000,000 data elements (mode=Random) and 5 types
Method Time % of optimal
If/Else 179.67 100.00
TypeHandleDictionary 321.33 178.85
TypeDictionary 377.67 210.20
Switch 492.67 274.21

Testing 3 iterations with 5,000,000 data elements (mode=Random) and 10 types
Method Time % of optimal
If/Else 271.33 100.00
TypeHandleDictionary 312.00 114.99
TypeDictionary 374.33 137.96
Switch 490.33 180.71

Testing 3 iterations with 5,000,000 data elements (mode=Random) and 15 types
Method Time % of optimal
TypeHandleDictionary 312.00 100.00
If/Else 369.00 118.27
TypeDictionary 371.67 119.12
Switch 491.67 157.59

Testing 3 iterations with 5,000,000 data elements (mode=Random) and 20 types
Method Time % of optimal
TypeHandleDictionary 335.33 100.00
TypeDictionary 373.00 111.23
If/Else 462.67 137.97
Switch 490.33 146.22

Testing 3 iterations with 5,000,000 data elements (mode=Random) and 25 types
Method Time % of optimal
TypeHandleDictionary 319.33 100.00
TypeDictionary 371.00 116.18
Switch 483.00 151.25
If/Else 562.00 175.99

Testing 3 iterations with 5,000,000 data elements (mode=Random) and 50 types
Method Time % of optimal
TypeHandleDictionary 319.67 100.00
TypeDictionary 376.67 117.83
Switch 453.33 141.81
If/Else 1,032.67 323.04

On my machine at least, the type handle dictionary approach beats all of the others for anything over 15 different types when the distribution
of the types used as input to the method is random.

If on the other hand, the input is composed entirely of the type that is checked first in the if/else chain that method is much faster:


Testing 3 iterations with 5,000,000 data elements (mode=UniformFirst) and 50 types
Method Time % of optimal
If/Else 39.00 100.00
TypeHandleDictionary 317.33 813.68
TypeDictionary 396.00 1,015.38
Switch 403.00 1,033.33

Conversely, if the input is always the last thing in the if/else chain, it has the opposite effect:


Testing 3 iterations with 5,000,000 data elements (mode=UniformLast) and 50 types
Method Time % of optimal
TypeHandleDictionary 317.67 100.00
Switch 354.33 111.54
TypeDictionary 377.67 118.89
If/Else 1,907.67 600.52

If you can make some assumptions about your input, you might get the best performance from a hybrid approach where you perform if/else checks for the few types that are most common, and then fall back to a dictionary-driven approach if those fail.

Is else if faster than switch() case?

For just a few items, the difference is small. If you have many items you should definitely use a switch.

If a switch contains more than five items, it's implemented using a lookup table or a hash list. This means that all items get the same access time, compared to a list of if:s where the last item takes much more time to reach as it has to evaluate every previous condition first.

Which is Faster and better, Switch Case or if else if?

Your first example is simply wrong. You need elseif instead of just else.

If you use if..elseif... or switch is mainly a matter of preference. The performance is the same.

However, if all your conditions are of the type x == value with x being the same in every condition, switch usually makes sense. I'd also only use switch if there are more than e.g. two conditions.

A case where switch actually gives you a performance advantage is if the variable part is a function call:

switch(some_func()) {
case 1: ... break;
case 2: ... break;
}

Then some_func() is only called once while with

if(some_func() == 1) {}
elseif(some_func() == 2) {}

it would be called twice - including possible side-effects of the function call happening twice. However, you could always use $res = some_func(); and then use $res in your if conditions - so you can avoid this problem alltogether.

A case where you cannot use switch at all is when you have more complex conditions - switch only works for x == y with y being a constant value.

If vs. Switch Speed

The compiler can build jump tables where applicable. For example, when you use the reflector to look at the code produced, you will see that for huge switches on strings, the compiler will actually generate code that uses a hash table to dispatch these. The hash table uses the strings as keys and delegates to the case codes as values.

This has asymptotic better runtime than lots of chained if tests and is actually faster even for relatively few strings.

Is there any significant difference between using if/else and switch-case in C#?

SWITCH statement only produces same assembly as IFs in debug or compatibility mode. In release, it will be compiled into jump table (through MSIL 'switch' statement)- which is O(1).

C# (unlike many other languages) also allows to switch on string constants - and this works a bit differently. It's obviously not practical to build jump tables for strings of arbitrary lengths, so most often such switch will be compiled into stack of IFs.

But if number of conditions is big enough to cover overheads, C# compiler will create a HashTable object, populate it with string constants and make a lookup on that table followed by jump. Hashtable lookup is not strictly O(1) and has noticeable constant costs, but if number of case labels is large, it will be significantly faster than comparing to each string constant in IFs.

To sum it up, if number of conditions is more than 5 or so, prefer SWITCH over IF, otherwise use whatever looks better.

Javascript switch vs. if...else if...else

Answering in generalities:

  1. Yes, usually.
  2. See More Info Here
  3. Yes, because each has a different JS processing engine, however, in running a test on the site below, the switch always out performed the if, elseif on a large number of iterations.

Test site

If vs if-else vs switch when each condition results in a return

If you have a lot of cases, then the switch approach is the preferred method. The reason is because the first two requires essentially a linear search through all the if-statements. So it is O(N) to the number of cases you have.

On the other hand, switch statements are optimized differently and can be either O(log(N)) or even O(1) for finding that correct case.


How can the compiler achieve O(log(N)) or even O(1)?

  • Binary search of the case values will allow it to be done in O(log(N)).
  • If the case values are dense enough, the compiler may even use a jump table indexed by the case variable. In that case it is O(1).

Why switch is faster than if

Because there are special bytecodes that allow efficient switch statement evaluation when there are a lot of cases.

If implemented with IF-statements you would have a check, a jump to the next clause, a check, a jump to the next clause and so on. With switch the JVM loads the value to compare and iterates through the value table to find a match, which is faster in most cases.

Need to know switch performance C#

Now here i need to no is there any performance issue to use multiple
points of exit

Your question is the epitome of premature optimization.

My suggestion, if you really want to know, is to write the method out both ways - once with return statements in each case and once with a single return after the switch statement. Then decompile each to intermediate language for comparison.

You still won't be able to make any certain statement about performance without doing actual measurement by profiling.

But, I think it's quite safe to say that any difference, if any, will be extremely miniscule. The end result should be nothing more than comparing the value to the constant strings, and when matched pushing the value and the stack and returning. The compiler will likely optimize away the assignment to a temporary variable, seeing that it will only be used as a return value.

Furthermore, some switch statements are significantly optimized by the compiler. See https://stackoverflow.com/a/395965/224087 and https://stackoverflow.com/a/126507/224087 for more information of switch statement performance and optimization.

This code you are questioning the performance of will only be a handful or two of CPU operations - a truly tiny amount of time to be concerned with.

if else vs switch performance in java

Switch perf is better than if else as in case of switch there will be one time evaluation . Once it evaluated the switch it knows which case needs to be executed but in case of if else it has to go through all conditions in case of worst scenario.

The longer the list condition, better will be switch performance but for shorter list (just two conditions), it can be slower also

From Why switch is faster than if

With switch the JVM loads the value to compare and iterates through
the value table to find a match, which is faster in most cases



Related Topics



Leave a reply



Submit