有没有快速有效的方法来找到由对象组成的int
最大值?我的意思是,我可以实现循环,但我正在寻找一些已经调整到最大速度的 API 函数,因为它正在处理相当大量的数据。NSArray
NSDictionary
for
[(int, string, string), (int, string, string), (int, string, string)]
我尝试过使用,valueForKeyPath
但到目前为止这对我没有帮助,因为它适用于“普通” NSArray 对象。
有没有快速有效的方法来找到由对象组成的int
最大值?我的意思是,我可以实现循环,但我正在寻找一些已经调整到最大速度的 API 函数,因为它正在处理相当大量的数据。NSArray
NSDictionary
for
[(int, string, string), (int, string, string), (int, string, string)]
我尝试过使用,valueForKeyPath
但到目前为止这对我没有帮助,因为它适用于“普通” NSArray 对象。
出于好奇,我对valueForKeyPath:
与简单迭代进行了一些比较。在我运行 OS X 10.8.2 的 iMac core i7 上,对于 10M 个元素的数组,简单迭代的速度大约是两倍。
这是我制作的测试程序:
#import <Foundation/Foundation.h>
#undef NDEBUG
#import <assert.h>
#import <limits.h>
#import <stdio.h>
#import <stdlib.h>
#define ELEMENTS_IN_ARRAY 10000000
NSArray *newArrayWithDictionaryElementCount(int count) {
NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 0; i < count; ++i) {
[arr addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"value%d", i], @"string",
[NSNumber numberWithInt:rand()], @"int",
nil]];
}
return arr;
}
int maxIntValueByKeyPathInArray(NSArray *arr) {
return [(NSNumber *)[arr valueForKeyPath:@"@max.int"] intValue];
}
int maxIntValueByIterationInArray(NSArray *arr) {
int max = INT_MIN;
for (NSDictionary *dict in arr) {
int val = [(NSNumber *)[dict valueForKey:@"int"] intValue];
if (val > max) {
max = val;
}
}
return max;
}
NSTimeInterval timeExecutionOf(void(^blockToTime)(void)) {
NSDate *start = [NSDate date];
blockToTime();
return -[start timeIntervalSinceNow];
}
int main (int argc, const char *argv[]) {
srand(time(NULL));
@autoreleasepool {
NSArray *arr = newArrayWithDictionaryElementCount(ELEMENTS_IN_ARRAY);
assert(maxIntValueByIterationInArray(arr) == maxIntValueByKeyPathInArray(arr));
(void) printf("Time by key path: %f s\n", timeExecutionOf(^{ maxIntValueByKeyPathInArray(arr); }));
(void) printf("Time by iteration: %f s\n", timeExecutionOf(^{ maxIntValueByIterationInArray(arr); }));
}
return 0;
}
我机器上的结果:
$ clang -fobjc-arc -framework Foundation -O4 -march=corei7 -o arraytest arraytest.m
$ ./arraytest
Time by key path: 1.809646 s
Time by iteration: 0.886023 s
我的假设是,对于这些数据结构,迭代解决方案的速度已经差不多了。不必为每个数组元素进行字典查找。此外,这种定制的迭代解决方案受益于知道所有NSNumber
对象都有int
值;用于isGreaterThan:
比较会稍微减慢速度(但它仍然比 快valueForKeyPath:
)。任何通用库方法几乎肯定会在内部产生这种惩罚……</p>
我现在不知道这是不是很快,但您可以使用内置@max
运算符valueForKeyPath:
:
NSArray *array = @[
@{ @"value" : @5, @"name" : @"foo"},
@{ @"value" : @7, @"name" : @"bar"},
@{ @"value" : @3, @"name" : @"abc"}
];
NSNumber *maximum = [array valueForKeyPath:@"@max.value"];
NSLog(@"%@", maximum);
// Output: 7
在这个例子中,value
是字典的键,值是一个NSNumber
对象,因为你不能int
在字典中存储一个。
(请参阅“键值编码编程指南”中的集合运算符。)
更新:这绝对不是最快的解决方案,正如 Arkku 在他的回答中所表明的那样。
是的,有一种更好的方法来对包含NSDictionary
. 在给定的代码片段中,它包含位置字典。每个字典对象都由 Name 和 Distance 键组成。
该数组将如下所示:
(
{ name = "Electronics Store";
distance = 9;
},{ name = "Caffeteria Store";
distance = 29;
}
)
这里的排序是根据字典的“键距离”进行的。请确保键距离必须是 int 值。
例如 :
[detail_dict setValue:[NSNumber numberWithInt:[distance intValue]] forKey:@"distance"];
注意:它将距离作为一个 int 值进行排序。
之后只需对以下默认方法进行排序NSMutableArray
:代码:
[arr_details sortUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES]]]