使用谓词进行过滤需要花费大量时间

时间:2018-08-25 17:56:43

标签: ios swift regex xcode performance

我在数组中有40k个字符串。我想过滤数组,以便仅获取匹配的字符串。我有一些先决条件,例如它之间可以有分隔符,应该是单词搜索,搜索可以有多个单词。因此,我使用了正则表达式,这需要很多时间。

以下是我在此处仅为表示目的而生成的代码。

var arr = [String]()
for index in stride(from: 0, to: 40000, by: 1) {
    arr.append("Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.")
}

// We specify the words to be searched here
let searchTexts = ["aliqua", "Ut"]

// The time the execution started
print(Date().timeIntervalSince1970)


let predicate = NSPredicate(format: "SELF matches[cd] %@", ".*\\b\(searchTexts.joined(separator: "[ ,.!?;:\"(')-]*"))\\b.*")
let fil = arr.filter { (str) -> Bool in
    return predicate.evaluate(with: str)
}

// The time the execution stopped
print(Date().timeIntervalSince1970)

在iOS模拟器中,耗时2秒。它需要更多的设备空间。

如何改善正则表达式?我搜索了很多网站,但并没有帮助我。

编辑:

由于涉及核心数据,上述问题已被修改。

我现在的实际问题是我们如何将相同的逻辑应用于核心数据提取?

1 个答案:

答案 0 :(得分:1)

如果只需要部分匹配,则不要使用需要整个字符串匹配的方法。 NSPredicateMATCHES需要完整的字符串匹配,并且您必须使用.*或类似的名称来确保。但是,.*贪婪圆点图案会占据整行,然后回溯来容纳后续图案的文本。 .*之后的模式越多,模式的效率就越低。

您需要使用一种方法,该方法将允许部分匹配,从而使您摆脱.*,例如range(of:options:range:locale:),同时通过.regularExpression选项。

在上述情况下,您可以删除let predicate = NSPredicate(format: "SELF matches[cd] %@", ".*\\b\(searchTexts.joined(separator: "[ ,.!?;:\"(')-]*"))\\b.*"并将return predicate.evaluate(with: str)替换为

return str.range(of: "\\b\(searchTexts.joined(separator: "[ ,.!?;:\"(')-]*"))\\b", options: .regularExpression) != nil

请参阅new regex demo(56个步骤)和your regex demo(541个步骤)。