from my past experience and stackoverflow, I learned that String.ToLower() is bad in performance. Now I have the following issue, I need to filter out or do a specific action when specific words are in a giant list.
Old approach, which I want to fix:
if (input.Any(i => i.ToLower() == "alle" || i.ToLower() == "all" || i.ToLower() == "none")
{
// do something
}
I was thinking of using a hashset, but I am questioning the performance and how it handles the case sensitivity, I basically dont care about the case sensitivity. Does it make sense for me to use the hashset?
my current suggestion as a solution:
var unwantedInputsSet = new HashSet<string> {"alle", "all", "none"};
if (input.Any(i => i => unwantedInputsSet.Contains(i)))
{
// do something
}
Is there any better alternative to this or not. Do you have any ideas how to approach this better?
You can pass comparer to the HashSet, for example StringComparer.InvariantCultureIgnoreCase:
var unwantedInputsSet = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) {"alle", "all", "none"};
if (input.Any(i => unwantedInputsSet.Contains(i)))
{
// do something
}
Or, as suggested in comments, use pattern matching:
if (input.Any(i => i.ToLower() is "alle" or "all" or "none")
{
// do something
}
Which should be turned by compiler into code similar to yours (though ToLower should be called once).
As for performance - it can be highly depended on the actual data and you should measure it using expected datasets. For small search set HashSet can be performing worse than several comparisons like:
var cmpr = StringComparison.InvariantCultureIgnoreCase;
if (input.Any(i => string.Equals(i, "alle", cmpr) || string.Equals(i, "all", cmpr) || string.Equals(i, "none", cmpr)))
{
// do something
}
For such benchmarking I recommend looking into BenchmarkDotNet.
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