根据我过去的经验和 stackoverflow,我了解到 String.ToLower() 的性能很差。现在我遇到以下问题,当特定单词出现在巨大列表中时,我需要过滤掉或执行特定操作。
旧方法,我想修复:
if (input.Any(i => i.ToLower() == "alle" || i.ToLower() == "all" || i.ToLower() == "none")
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
我正在考虑使用哈希集,但我质疑性能以及它如何处理区分大小写,我基本上不关心区分大小写。使用哈希集对我来说有意义吗?
我目前的建议作为解决方案:
var unwantedInputsSet = new HashSet<string> {"alle", "all", "none"};
if (input.Any(i => i => unwantedInputsSet.Contains(i)))
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的替代方案。您有什么想法如何更好地解决这个问题吗?
您可以将比较器传递给HashSet,例如StringComparer.InvariantCultureIgnoreCase:
var unwantedInputsSet = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) {"alle", "all", "none"};
if (input.Any(i => unwantedInputsSet.Contains(i)))
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
或者,按照评论中的建议,使用模式匹配:
if (input.Any(i => i.ToLower() is "alle" or "all" or "none")
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
编译器应该将其转换为与您的代码类似的代码(尽管ToLower应该调用一次)。
至于性能 - 它可能高度依赖于实际数据,您应该使用预期的数据集来测量它。对于小型搜索集,HashSet其性能可能比几种比较更差,例如:
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
}
Run Code Online (Sandbox Code Playgroud)
对于此类基准测试,我建议查看BenchmarkDotNet。
| 归档时间: |
|
| 查看次数: |
644 次 |
| 最近记录: |