首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化NSRegularExpression性能

优化NSRegularExpression性能
EN

Stack Overflow用户
提问于 2017-01-17 19:49:44
回答 2查看 2.2K关注 0票数 1

我的应用程序有一个提要,它可以包含URL、#hashtag和@推荐的帖子。我用一个叫做ActiveLabel的吊舱来显示它们。这个吊舱做得很好,但是我的饲料在滚动时稍微滞后了。我的提要是一个UICollectionView,而单元格生成稍微滞后一些。当我滚动的时候,我分析了我的应用程序,并分析了滞后的峰值。这种滞后几乎是不明显的,但它使我恼火。

正如您所看到的,主要的违法者是NSRegularExpression搜索。

我试图在没有数据类型实例的情况下,使用.contains(),通过禁用数据检测来稍微优化这一点。这使其速度略有加快,但滞后的峰值依然存在。

代码语言:javascript
复制
let enabledTypes:[ActiveType] = {
        var types = [ActiveType]()
        if ad.caption.current.string.contains("#") { types.append(.hashtag) }
        if ad.caption.current.string.contains("@") { types.append(.mention) }
        if ad.caption.current.string.contains("://") { types.append(.url) }
        if ad.caption.canExpand { types.append(seeMore) }
        return types
    }()
label.enabledTypes = enabledTypes

我还跟踪了这篇文章中的每一步,这是轻轻松松的,但还不够。所以我得修一下横梁。

ActiveLabel使用的regex语句是

代码语言:javascript
复制
static let hashtagPattern = "(?:^|\\s|$)#[\\p{L}0-9_]*"
static let mentionPattern = "(?:^|\\s|$|[.])@[\\p{L}0-9_]*"
static let urlPattern = "(^|[\\s.:;?\\-\\]<\\(])" + "((https?://|www\\.|pic\\.)[-\\w;/?:@&=+$\\|\\_.!~*\\|'()\\[\\]%#,☺]+[\\w/#](\\(\\))?)" + "(?=$|[\\s',\\|\\(\\).:;?\\-\\[\\]>\\)])"

它把它们和

代码语言:javascript
复制
 static func getElements(from text: String, with pattern: String, range: NSRange) -> [NSTextCheckingResult]{
    guard let elementRegex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) else { return [] }
    return elementRegex.matches(in: text, options: [], range: range)
}

搜索其他regexe,以检测hashtag和所提到的内容,但我没有发现任何有意义的地方。

我试图将标签布局到后台线程上,但显然失败了,因为UI不喜欢在后台线程上执行。我可以重写ActiveLabel,主要在后台线程上工作,并且可以使用回调而不是返回类型,但我想避免这种情况。

我在以下方面检测到数据的一些字符串示例:

"Arnie says,Aspen,Str. Small,Varm神jakke,Veldig!Fremst r ubrukt. Kun brukt et,rett og slett har alt for mange jakker #城市#arnie #jakker #ubrukt“ Skjorte pent brukt I “让·保罗·甘塞(Jean Paul genser I) 100%”,“pent brukt✨er Istr.m.”,“男士丝绒里特”,“过客xs-s!”

正如您所看到的,我们的用户主要是hashtag之类的东西,所以其中一个是最重要的。

是否有任何方法可以改进NSRegularExpression 或regex语句以避免性能下降?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-17 20:44:05

如@raidfive所示,最有可能的做法是提前创建一个或多个NSRegularExpression实例,并在需要时重用它们。

请注意,由于是regexes的创建/编译对您的时间配置文件产生了最大的影响(至少在您共享的时间概要文件中),缓存regexes可能会为您赢得足够的性能,您不再需要只启用所需的检测元素的中间优化。在这种情况下,您只需要一个regex (表示所有可能的元素类型的检测),所以缓存/重用很容易。

此外,请注意,您的中间“优化”可能实际上并没有提高性能--它甚至可能会损害性能。匹配正则表达式,无论多么复杂,都需要搜索整个字符串(粗略地)一次。试图确定要检测哪些元素类型意味着要多次搜索字符串--每次contains("#") (etc)测试一次,然后再一次根据正则表达式计算字符串。重复的字符串搜索可能比编译单个正则表达式花费更多。

如果在实现了单个缓存的通用正则表达式之后,仍然(不知怎么地)限制了regex性能,那么您可以缓存多个正则表达式,每个搜索场景都缓存一个正则表达式。组合计算的结果可能是这样的,与需要处理的字符串相比,仍然有更少的不同正则表达式,因此,如果在用户开始滚动之前编译它们,那么在滚动期间编译它们的时间成本就不高了。但是,根据上一段,只有当您有一种廉价的(即不是字符串搜索)方法来检测每个字符串需要哪个正则表达式时,这才有意义。

票数 4
EN

Stack Overflow用户

发布于 2017-01-17 19:56:45

您可以尝试在变量(类或实例)中创建和存储NSRegularExpression实例,因此您只需要创建它们一次。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41705728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档