TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

<< Back to C-SHARP

C# String Switch Examples

Match string cases with a switch statement for improved performance. Test string literals.
String switch. Often we need to make a decision in code based on a string's value. We can test characters, or lengths, but sometimes we need to match entire strings.Switch
Switch notes. With a switch statement, the C# compiler implements hidden optimizations to speed up matching. This can help programs go faster.
An example. Here we use switch (on strings) to test whether a string is a moth name. Let's call our method that does this "IsMoth."

Tip: No fancy collections like a Dictionary or complex if-else chains are required here.

And: The C# compiler (our friend) will try to improve the switch's performance based on its internal heuristic.

IsMoth: Contains a switch case with 7 moth names in it. If any of those strings equal the parameter, it returns true. We have a moth name.

C# program that uses switch using System; class Program { static void Main() { Console.WriteLine(IsMoth("Ash Pug")); Console.WriteLine(IsMoth("The Dev Codes")); } static bool IsMoth(string value) { switch (value) { case "Atlas Moth": case "Beet Armyworm": case "Indian Meal Moth": case "Ash Pug": case "Latticed Heath": case "Ribald Wave": case "The Streak": return true; default: return false; } } } Output True False
Internals. String switches are sometimes compiled into a custom Dictionary. Having 6 or more string cases and a default case resulted in the compiler generating a Dictionary.
Switch complexity 7 strings + default 6 strings + default 5 strings + default [and fewer] Compilation ldsfld class [mscorlib]System.Collections.Generic.Dictionary ldsfld class [mscorlib]System.Collections.Generic.Dictionary L_000b: call bool [mscorlib]System.String::op_Equality Output Compiler generated a Dictionary. Compiler generated a Dictionary. Compiler generated series if/conditionals.
ToLower. Switch cases must be constant. We cannot compare them case-insensitively without custom code. Here we normalize the string values with ToLower before entering the string switch.

Then: All the cases are lowercase. This results in a case-insensitive string switch.

Tip: The uppercase string "WHIPPET" was found to be a dog type. The value.ToLower() expression will match "whippet" in lowercase.

ToLower
C# program that uses switch, ToLower using System; class Program { static void Main() { Console.WriteLine(IsDogCaseInsensitive("WHIPPET")); Console.WriteLine(IsDogCaseInsensitive("sphynx")); } static bool IsDogCaseInsensitive(string value) { switch (value.ToLower()) { case "irish terrier": case "jagdterrier": case "keeshond": case "sulimov dog": case "whippet": case "eurasier": case "brittany": return true; default: return false; } } } Output True False
Null case. Most switch cases in C# a red on values (like 10 or 20) or string literals. But with the string switch we can match the null literal.

Note: In .NET Framework internals, null is like a 0 value, so it too is a constant—we call it the null literal constant.

C# program that uses null case in switch using System; class Program { static void Main() { foreach (string value in new string[] { null, "" }) { switch (value) { case null: // Can have a null case. Console.WriteLine("CASE NULL"); break; case "": // Empty string case also works. Console.WriteLine("CASE EMPTY"); break; } } } } Output CASE NULL CASE EMPTY
Abbreviations. A switch can handle abbreviations or synonyms. For example, in Excel spreadsheets, users will enter different column titles that mean the same thing.

So: We can use switches to tell the computer that "Height" is an abbreviation for "Ht."

Trim: We can use the Trim, TrimEnd, and TrimStart methods to try to normalize the input further.

TrimTrimEnd, TrimStart

Here: We handle abbreviations in a string switch, and also remove ending spaces. Further string logic could be added.

C# program that uses switch with abbreviations, Trim method using System; class Program { static bool IsHeight(string value) { // Match the trimmed value and return a bool. switch (value.Trim()) { case "Ht.": case "Height": return true; } return false; } static void Main() { Console.WriteLine("HEIGHT: {0}", IsHeight("Height")); Console.WriteLine("HEIGHT: {0}", IsHeight("Ht. ")); Console.WriteLine("HEIGHT: {0}", IsHeight("Width")); } } Output HEIGHT: True HEIGHT: True HEIGHT: False
Benchmark. Here we test a string switch against an if-else chain expression. The C# compiler turns the string switch into a Dictionary of strings. Then, cases perform a Dictionary lookup.

Version 1: We use the string switch to test the tree name strings. The switch is run in a tight loop.

Version 2: We use an expression, which is compiled into something like a series of if-else statements.

If

Result: The string switch statement is faster. If we cannot test for the most common string first, a string switch can improve performance.

C# program that benchmarks string switch using System; using System.Diagnostics; class Program { const int _max = 100000000; static void Main() { string[] trees = new string[] { "Adler", "Persimmon", "???" }; int treeCount = 0; var s1 = Stopwatch.StartNew(); // Version 1: use string switch. for (int i = 0; i < _max; i++) { foreach (string tree in trees) { if (IsTree(tree)) { treeCount++; } } } s1.Stop(); var s2 = Stopwatch.StartNew(); // Version 2: use expression. for (int i = 0; i < _max; i++) { foreach (string tree in trees) { if (IsTreeExpression(tree)) { treeCount++; } } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.Read(); } static bool IsTree(string value) { switch (value) { case "Alder": case "Elderberry": case "Chestnut": case "Guava": case "Willow": case "Elm": case "Persimmon": return true; default: return false; } } static bool IsTreeExpression(string value) { return (value == "Alder" || value == "Elderberry" || value == "Chestnut" || value == "Guava" || value == "Willow" || value == "Elm" || value == "Persimmon"); } } Output 32.94 ns switch (IsTree) 78.21 ns if (IsTreeExpression)
Result, above benchmark. In 2017, the switch version benchmarks faster. But here is an important point—in 2008 when I first tried this benchmark, the if-statement worked faster.

So: It may be useful to test the code on a system before you deploy it. Things might be wrong on the Internet.

Note: To achieve even better performance, you can try reordering the strings in an optimal way.

Tree: For complex situations where we have many strings and want to test them in a loop, consider a directed acyclic graph.

Tree
A summary. For performance, switches can be slower than if-statements. Often these small slowdowns do not matter. But when they do, an understanding of how switches work is important.
© TheDeveloperBlog.com
The Dev Codes

Related Links:


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf