草庐IT

ios - swift 3 : most performant way to check many strings with many regular expressions

coder 2024-01-29 原文

我确实有一个包含数百个字符串的列表和一个包含 10k 正则表达式的数组。

我现在必须遍历所有字符串并检查 10k 正则表达式中的哪些匹配。执行此操作的最高效方法是什么?

目前我正在这样做:

myRegularExpression.firstMatch(in: myString, options: myMatchingOption, range: NSMakeRange(0, myString.characters.count)) == nil

其中 myRegularExpression 是一个 NSRegularExpression 存储以供重用,myMatchingOptionNSRegularExpression.MatchingOptions(rawValue: 0)

是否有更快、更高效的方法来检查字符串是否与这 10k 正则表达式中的一个匹配?

编辑:

我不仅需要知道我的 10k 正则表达式是否适合,还需要知道是哪一个。所以目前我在 for 循环中确实有一个 for 循环:外部循环遍历我的几百个字符串,对于这些字符串中的每一个,我遍历我的 10k 规则并查看是否有一个规则适合(当然,如果一个适合我可以停止对于那个字符串,大致如下:

for string in stringsToCheck {
    for rule in myRules {
        if string.matches(rule) {
            // continue with next string of stringsToCheck
        }
    }
}

最佳答案

根据您在哪个平台上运行它,使用多个线程分离工作可能会提供一些响应时间改进,但我相信对此真正显着的优化需要对正则表达式的性质有一些了解。

例如,如果表达式没有特定的优先顺序,您可以重新排列(重新排序)它们,使最可能的“匹配项”出现在列表中的第一位。这可以由表达式的提供者或使用某些函数来预估它们的复杂性(例如表达式的长度、可选符号或组合符号的存在)来预先评估。 或者它可以通过收集(和持久化)每个表达式的命中/未命中计数来进行统计评估。但当然,这种优化假设每个字符串都将匹配至少一个表达式,并且应用 80/20 规则(即 20% 的表达式匹配 80% 的字符串)。

如果表达式非常简单并且只使用字母模式,那么使用匹配函数的更多“手动”实现(而不是正则表达式)会获得更好的性能。在最好的情况下,简单的字母模式可以转换为字符树,并在性能改进方面产生数量级。

请注意,这些解决方案并不相互排斥。例如,如果大部分表达式是简单模式而只有少数具有复杂模式,那么您不必把婴儿和洗澡水一起扔掉:您可以将简单模式优化应用于规则的子集,并且对剩余的复杂循环使用“强力”嵌套循环。

我过去遇到过类似的问题,需要在数十万条记录上应用数千条规则来处理保险 claim 。传统的“专家系统”方法是创建一个规则列表并通过它运行每条记录。显然,这将花费大量时间(例如 2 个月的执行时间来处理一个月的 claim )。以一种不那么“纯粹”的心态看待它,我能够说服我的客户规则应该分层定义。所以我们将它们分成一组资格规则和一组决策规则。然后我们通过创建资格组和决策组进一步细化结构。我们最终得到的是一个粗略的树结构,其中规则允许系统缩小应应用于给定记录的规则数量。这样,250,000 条记录的 6 周处理时间缩短为 7 小时(请注意,这是 1988 年的情况)。

所有这一切都表明,退一步回到要解决的问题的本质可能会提供一些优化机会,这些机会在仅查看一个过程选项的机制时是看不到的。

关于ios - swift 3 : most performant way to check many strings with many regular expressions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45994161/

有关ios - swift 3 : most performant way to check many strings with many regular expressions的更多相关文章

随机推荐