【问题标题】:Fastest way possible to validate a string to be only Alphas, or a given string set验证字符串是否仅为 Alpha 或给定字符串集的最快方法
【发布时间】:2011-12-06 19:18:23
【问题描述】:

我需要尽可能快的方法来根据给定规则验证输入字符串。在这种情况下,不要说只有 Alpha 字符。

我能想到很多冗长和非冗长的方法。然而,执行速度至关重要。因此,如果有人能提供他们的智慧珍珠,我将不胜感激。

我避免使用正则表达式来避免创建表达式对象的开销。但是,如果人们认为这是最快的选择,我愿意重新审视它。

当前的想法包括: 1)

    internal static bool Rule_AlphaOnly(string Value)
    {
        char[] charList = Value.ToCharArray();
        for (int i = 0; i < charList.Length; i++)
        {
            if (!((charList[i] >= 65 && charList[i] <= 90) || (charList[i] >= 97 && charList[i] <= 122)))
            {
                return false;
            }
        }
        return true;
    }

2)

    char[] charList = Value.ToCharArray();
    return charList.All(t => ((t >= 65 && t <= 90) || (t >= 97 && t <= 122)));

考虑过使用“包含”方法。

欢迎任何想法。 非常感谢

3) for (int i = 0; i

【问题讨论】:

  • 最好的方法是尝试一堆不同的解决方案,然后分析它们。对大约 1000 个字符串执行此操作,并测量每种方法经过的秒数。

标签: c# string contains alpha


【解决方案1】:

通过删除ToCharArray 调用并避免复制,这两个代码都可以变得更高效:您可以直接访问字符串的各个字符。

在这两种方式中,我强烈选择第二种方式,除非你能证明它太慢了。只有这样我才会切换到第一个,但将for 循环替换为foreach 循环。

哦,您的代码都没有正确处理 Unicode。如果您使用了具有正确字符类的正则表达式,那么这将不是问题。 正确性第一,性能第二。

【讨论】:

  • 实际上,.NET 的正则表达式不能正确处理 Unicode。它们在 BMP 之外的任何东西上都不能正常工作(这一切都只是代理)。一个例子:Regex.IsMatch("?", @"\p{Lu}")
  • @Porges 不错。但是,如果即使是正则表达式也不能正确处理这个问题,手动处理可能会更加困难——例如,char.IsLetter 也不能正确处理这个问题。
  • 是的,在 .NET 中处理 Unicode 很糟糕。要遍历 Unicode 字符串,您需要手动使用 char.IsSurrogate 方法,或使用 StringInfo (另外将处理组合字符)。然后你可以在字符上使用char.IsLetter(string,index) 来正确处理它。
  • 好吧...我已经完成了以下内容,有任何反对意见或进一步的问题吗? for (int i = 0; i
  • @DubMan 嗯。与@Porges 不同,我发现char.IsLetter(value, i) 的效果并不比其他变体好,至少在他发布的示例中是这样。也许它对组合变音符号有影响,我还没有测试过。
【解决方案2】:

不知道这个速度,但是怎么样......

foreach(char c in Value)
{
   if(!char.IsLetter(c))
      return false;
}

【讨论】:

  • 好吧,这使用了 for each 我相信它仍然比 for i char[i] 循环器慢,但是会查看 char.IsLetter 位。谢谢
  • @DubMan 不要相信,衡量。没有技术原因,这应该比带有索引的 for 循环慢。
  • 我通常总是找到一个 for 比一个 for each 更快。这里的上面可以用一个可爱的一行来表示:return _value.All(char.IsLetter);但这当然是使用 Linq,而且速度慢是出了名的。因此,我将在负载上测试这些示例。谢谢大家的意见。
【解决方案3】:

C#编译器和JIT优化完成后,我怀疑这会比手动for循环慢很多:

return Value.All(char.IsLetter);

如果您需要检查任意字符集,请执行以下操作:

var set = new HashSet<char>(new[] { 'a', 'b', 'c' /* Etc... */ });
return Value.All(set.Contains);

除非set 是微不足道的并且可以通过少数ifs 有效地“模拟”,否则哈希表查找必然是一个最快的解决方案。

【讨论】:

    猜你喜欢
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 2023-02-18
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 2014-01-07
    • 2021-09-22
    相关资源
    最近更新 更多