gpt4 book ai didi

ios - NSString rangeOfString 执行缓慢

转载 作者:行者123 更新时间:2023-11-28 21:49:04 25 4
gpt4 key购买 nike

我有大约 10-15 次检查,我正在检查字符串中是否存在子字符串。其中一项检查的示例如下:

if([request.URL.absoluteString.lowercaseString rangeOfString:@"/group/editgroupmembers?groupid"].location != NSNotFound)  

我发现通过这些检查需要几秒钟。为了确认,我调试了应用程序,发现每次检查都需要 1 秒以上的时间。
rangeOfStringApple's检查子字符串是否存在的推荐方法。
但为什么需要这么长时间?

最佳答案

Apple String Programming Guide您还将阅读:

If you simply want to determine whether a string contains a given pattern, you can use a predicate:

因此,在您的情况下,您可以使用谓词将您的搜索字符串与您的网址进行匹配,这应该会给您带来更好的性能:

NSString *path = @"/group/editgroupmembers?groupid";
NSPredicate *containsPred = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", path];

BOOL match = [containsPred evaluateWithObject:request.URL.absoluteString.lowercaseString];

您可以在 Apple Predicate Programming Guide 中阅读有关谓词的更多信息.

编辑

我做了一个快速基准测试来检查各种选项的性能。

  • 第一个选项是使用 rangeOfString:正如 OP 所做的那样。
  • 第二个选项是使用 NSPredicate .
  • 第三个选项将所有字符串放入一个数组中并使用filteredArrayUsingPredicate: 匹配整个数组。 .

基准测试将 100k 个随机数字字符串放入一个数组中,并使用不同的选项检查匹配短语“123”。这是基准代码:

- (void)benchmarkStringContainment {

// Setup of array to search through
NSMutableArray *arrayOfRandomStrings = [NSMutableArray array];
for (int i = 0; i < 100000; i++) {
NSString *stringToSearch = [NSString stringWithFormat:@"%lli", arc4random() % 100000000000];
[arrayOfRandomStrings addObject:stringToSearch];
}

// String we search for
NSString *matchPhrase = @"123";


// Method 1: rangeOfSubstring
NSUInteger matches1 = 0;
NSDate *date1 = [NSDate date];

for (int i = 0; i < 100000; i++) {
BOOL match = ([[arrayOfRandomStrings[i] lowercaseString] rangeOfString:matchPhrase].location != NSNotFound);
if (match) matches1++;
}

double timePassed1_ms = [date1 timeIntervalSinceNow] * -1000.0;
NSLog(@"Method 1: rangeOfString. Matches: %lu, time taken in ms: %f", (unsigned long)matches1, timePassed1_ms);


// Setup of NSPredicate
NSPredicate *containsPred = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", matchPhrase];

// Method 2: NSPredicate
NSUInteger matches2 = 0;
NSDate *date2 = [NSDate date];

for (int i = 0; i < 100000; i++) {
BOOL match = [containsPred evaluateWithObject:arrayOfRandomStrings[i]];
if (match) matches2++;
}

double timePassed2_ms = [date2 timeIntervalSinceNow] * -1000.0;
NSLog(@"Method 2: NSPredicate. Matches: %lu, time taken in ms: %f", (unsigned long)matches2, timePassed2_ms);


// Method 3: NSPredicate over NSArray
NSUInteger matches3 = 0;
NSDate *date3 = [NSDate date];

NSArray *filteredArray = [arrayOfRandomStrings filteredArrayUsingPredicate:containsPred];
matches3 = [filteredArray count];

double timePassed3_ms = [date3 timeIntervalSinceNow] * -1000.0;
NSLog(@"Method 3: NSPredicate over NSArray. Matches: %lu, time taken in ms: %f", (unsigned long)matches3, timePassed3_ms);

}

在 iPhone 5 上进行测试(调试)时,样本结果会在 200 毫秒到 500 毫秒左右产生结果。这是一个典型的输出:

2015-03-13 10:49:27.815 so29003576[1413:494702] Method 1: rangeOfString. Matches: 978, time taken in ms: 443.618000
2015-03-13 10:49:28.090 so29003576[1413:494702] Method 2: NSPredicate. Matches: 978, time taken in ms: 272.534013
2015-03-13 10:49:28.309 so29003576[1413:494702] Method 3: NSPredicate over NSArray. Matches: 978, time taken in ms: 217.999041

下一步,我多次重复基准测试(代码未显示),并对不同方法进行平均,以获得更具代表性的结果:

2015-03-13 10:54:01.728 so29003576[1423:495973] Method 1: rangeOfString. Repetitions: 50, average time taken in ms: 449.577812
2015-03-13 10:54:01.731 so29003576[1423:495973] Method 2: NSPredicate. Repetitions: 50, average time taken in ms: 276.818836
2015-03-13 10:54:01.732 so29003576[1423:495973] Method 3: NSPredicate over NSArray. Repetitions: 50, average time taken in ms: 222.459898

虽然这个小基准肯定不是数据独立的,但它表明了两个结果:

  1. 在一堆字符串中找到匹配短语的测试选项中最快的是选项 3,使用 filteredArrayUsingPredicate: ,这是选项 1 的两倍,rangeOfString: .选项 2,使用 NSPredicate直接迭代不同的字符串,比选项 3 的性能稍差。
  2. 基准测试在 100.000 个字符串中搜索匹配短语。正如 @gnasher729 在其中一条评论中指出的那样,OP 在他们的代码中一定有不同的问题,因为即使是最慢的方法也应该在 10 到 15 个 URL 上快几个数量级。

关于ios - NSString rangeOfString 执行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29003576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com