objective-c – 在大型NSString中有效地找到许多关键字中的第一个

objective-c – 在大型NSString中有效地找到许多关键字中的第一个,第1张

概述我需要在大型NSString中找到所有关键字(用于解析源代码),而我当前的实现速度太慢,但我不确定如何改进它. 我正在使用NSRegularExpression,基于它比我能编写的任何内容更优化的假设,但性能比我预期的要慢.有谁知道更快的实现方法? 目标字符串将包含utf-8字符,但关键字本身将始终为纯字母数字ascii.我想这可以用来优化一些东西? @implementation MyClass 我需要在大型Nsstring中找到所有关键字(用于解析源代码),而我当前的实现速度太慢,但我不确定如何改进它.

我正在使用NSRegularExpression,基于它比我能编写的任何内容更优化的假设,但性能比我预期的要慢.有谁知道更快的实现方法?

目标字符串将包含utf-8字符,但关键字本身将始终为纯字母数字ascii.我想这可以用来优化一些东西?

@implementation MyClass// i'm storing the regular Expression in a static variable,since it never changes and I need to re-use it oftenstatic NSRegularExpression *keywordsExpression;+ (voID)initialize{  [super initialize];  NSArray *keywords = [NSArray arrayWithObjects:@"accumsan",@"adipiscing",@"aliquam",@"aliquet",@"amet",@"ante",@"arcu",@"at",@"commodo",@"congue",@"consectetur",@"consequat",@"convallis",@"cras",@"curabitur",@"cursus",@"dAPIbus",@"diam",@"dolor",@"dui",@"elit",@"enim",@"erat",@"eros",@"est",@"et",@"eu",@"felis",@"fermentum",@"gravida",@"iaculis",@"ID",@"imperdIEt",@"integer",@"ipsum",@"lacinia",@"lectus",@"leo",nil];  Nsstring *pattern = [Nsstring stringWithFormat:@"\b(%@)\b",[keywords componentsJoinedByString:@"|"]; // \b(accumsan|adipiscing|aliquam|…)\b  keywordsExpression = [NSRegularExpression regularExpressionWithPattern:pattern] options:NSRegularExpressionCaseInsensitive error:NulL];}// this method will be called in quick succession,I need it to be a able to run tens// of thousands of times per second. The target string is big (50KB or so),but the// search range is short,rarely more than 30 characters- (NSRange)findNextKeyword:(Nsstring *)string inRange:(NSRange)range{  return [keywordsExpression rangeOfFirstMatchInString:string options:0 range:range];}@end

编辑根据@ CodeBrickIE的回答,我已经更新了我的代码,对整个字符串执行一次正则表达式搜索,并将匹配保存到缓存的NSIndexSet,然后每次调用该方法时,它在NSIndexSet中搜索关键字范围而不是搜索字符串.结果大约快一个数量级:

@implementation MyClassstatic NSRegularExpression *keywordsExpression;static NSIndexSet *keywordindexes = nil;+ (voID)initialize{  [super initialize];  NSArray *keywords = [NSArray arrayWithObjects:@"accumsan",[keywords componentsJoinedByString:@"|"]; // \b(accumsan|adipiscing|aliquam|…)\b  keywordsExpression = [NSRegularExpression regularExpressionWithPattern:pattern] options:NSRegularExpressionCaseInsensitive error:NulL];}- (voID)preparetoFindKeywordsInString:(Nsstring *)string{  NSMutableIndexSet *keywordindexesMutable = [[NSIndexSet indexSet] mutablecopy];  [keywordsExpression enumerateMatchesInString:string options:0 range:NSMakeRange(0,string.length) usingBlock:^(NSTextCheckingResult *match,NSMatchingFlags flags,BOol *stop){    [keywordindexesMutable addindexesInRange:match.range];  }];  keywordindexes = [keywordindexesMutable copy];}- (NSRange)findNextKeyword:(Nsstring *)string inRange:(NSRange)range{  NSUInteger foundKeywordMax = (foundCharacterSetRange.location == NSNotFound) ? string.length : foundCharacterSetRange.location;  NSRange foundKeywordRange = NSMakeRange(NSNotFound,0);  for (NSUInteger index = startingAt; index < foundKeywordMax; index++) {    if ([keywordindexes containsIndex:index]) {      if (foundKeywordRange.location == NSNotFound) {        foundKeywordRange.location = index;        foundKeywordRange.length = 1;      } else {        foundKeywordRange.length++;      }    } else {      if (foundKeywordRange.location != NSNotFound) {        break;      }    }  }  return foundKeywordRange;}@end

这似乎运作良好,并且性能达到我想要的范围.我想等一下,看看是否有更多的建议,然后再接受这个.

解决方法 由于您需要关键字及其范围,我将使用enumerateMatchesInString:options:range:usingBlock:并实现一个块,该关键字将关键字作为键添加,并将范围作为值添加到NSMutableDictionary.

因此,在调用之后,您只需要调用整个字符串,并在字典中显示其范围内的所有关键字.

总结

以上是内存溢出为你收集整理的objective-c – 在大型NSString中有效地找到许多关键字中的第一个全部内容,希望文章能够帮你解决objective-c – 在大型NSString中有效地找到许多关键字中的第一个所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1001180.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存