比较/设置字符串的最快方法

发布于 2025-01-03 22:04:39 字数 930 浏览 3 评论 0原文

我有一个 Place 对象数组。每个 Place 对象都有一个 namecode 属性,都是字符串。每个 Place 对象已经有一个 code,但我需要从服务器查找 name 属性。我返回 2 个数组:一个包含名称,另一个包含代码。这些数组经过排序,以便 nameArray 中某个索引处的 namecodeArray 中同一索引处的 code 完全对应

我一直在循环 Place 对象数组,然后检查该 Placecode 属性是否与当前索引相同在codeArray中。如果是,我通过在 nameArray 中使用相同的索引来设置该 Placename

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
       }
    }
}

这可以工作,但速度不是很快 -循环浏览 1000 多个地点可能需要 30 秒。

有更快的方法吗?

I have an array of Place objects. Each Place object has a name and code property, both strings. Each Place object already has a code, but I need to look up the name property from a server. I get back 2 arrays: one contains name, the other codes. These arrays are ordered so that the name at some index in the nameArray corresponds exactly with the code at the same index of the codeArray.

I have been looping through the array of Place objects, then checking to see if the code property for that Place is the same as the current index in the codeArray. If it is, I set the name of that Place by using the same index in the nameArray:

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
       }
    }
}

This works but isn't terribly fast - it can take 30 seconds with 1000+ Places to loop through.

Is there a faster way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一抹苦笑 2025-01-10 22:04:39

与任何时候您尝试优化性能一样,您应该使用 Instruments 分析代码以找出实际瓶颈所在。也就是说,循环遍历 placeArray 中的每个名称并进行字符串比较是非常低效的。

像这样的事情怎么样?

NSMutableDictionary *placesByCode = [NSMutableDictionary dictionaryWithCapacity:[placesArray count]];
for (Place *aPlace in placesArray) {
    [dictionary setObject:aPlace forKey:aPlace.code];
}

NSMutableDictionary *namesByCode = [NSMutableDictionary dictionaryWithCapacity:[namesArray count]];
for (int i=0; i<[namesArray count]; i++) {
    NSString *name = [namesArray objectAtIndex:i];
    NSString *code = [codeArray objectAtIndex:i];
    [namesByCode setObject:name forKey:code];
}

for (NSString *code in namesByCode) {
    Place *place = [placesByCode objectForKey:code];
    place.name = [namesByCode objectForKey:namesByCode];
}

通过字典中的代码查找每个地点应该比手动循环遍历每个名​​称的整个地点数组要快得多。

As with anytime you're trying to optimize performance, you should profile the code using Instruments to find out where the bottleneck actually is. That said, looping through the placesArray for each name in the nameArray and doing a string comparison is pretty inefficient.

How about something like this?

NSMutableDictionary *placesByCode = [NSMutableDictionary dictionaryWithCapacity:[placesArray count]];
for (Place *aPlace in placesArray) {
    [dictionary setObject:aPlace forKey:aPlace.code];
}

NSMutableDictionary *namesByCode = [NSMutableDictionary dictionaryWithCapacity:[namesArray count]];
for (int i=0; i<[namesArray count]; i++) {
    NSString *name = [namesArray objectAtIndex:i];
    NSString *code = [codeArray objectAtIndex:i];
    [namesByCode setObject:name forKey:code];
}

for (NSString *code in namesByCode) {
    Place *place = [placesByCode objectForKey:code];
    place.name = [namesByCode objectForKey:namesByCode];
}

Looking up each place by its code in the dictionary should be quite a bit faster than manually looping through the whole place array for each name.

别在捏我脸啦 2025-01-10 22:04:39

您可以用于 NSArray -containsObject

if ([myarray containsObject:myObject]) {
    // ...
}

You can use for NSArray -containsObject

if ([myarray containsObject:myObject]) {
    // ...
}
苦笑流年记忆 2025-01-10 22:04:39

尝试在内循环中使用break语句。这样你就不需要每次都遍历整个循环。

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            break;
       }
    }
}

当您找到更多结果时,您还可以使第二个数组变得更小。它会花费你更多的内存,但 1000 个字符串无论如何也不算多。

NSMutableArray * tempCodeArray = [NSMutableArray arrayWithArray:codeArray];
for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [tempCodeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[tempCodeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            [tempCodeArray removeObjectAtIndex:j];
            break;
       }
    }
}

Try using a break statement in the inner loop. This way you don't need to loop through the entire loop each time.

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            break;
       }
    }
}

You could also make the second array become smaller as you find more results. It will cost you more memory but 1000 strings isn't much anyway.

NSMutableArray * tempCodeArray = [NSMutableArray arrayWithArray:codeArray];
for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [tempCodeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[tempCodeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            [tempCodeArray removeObjectAtIndex:j];
            break;
       }
    }
}
执笔绘流年 2025-01-10 22:04:39

问题不在于数组的计数,而是嵌入的 for 循环需要 O(n*n),在 Andrew 的解决方案中,只需 O(n)+O(n)+O(n)+ 查找所需的时间字典中键的对象,我猜它会在哈希表查找中,而且速度非常快。

科尔比,您可能会同意安德鲁的解决方案。如果您仍然想提高性能,那么一个好主意是先对数组进行排序,然后再进行查找。

希望这有帮助。

The problem was not the counting for the array, it's the embedded for loop which will take O(n*n) and in Andrew's solution, it's only O(n)+O(n)+O(n)+whatever take to find a object of the key in the dictionary, which i guess would be in a hash table lookup and that's really fast.

Colby, you probably will be ok with Andrew's solution. If you still wanna improve the performance, then a good idea would be sort the array's first then do lookup.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文