gpt4 book ai didi

ios - indexOfObjectsPassingTest 或 filteredArrayUsingPredicate 哪个性能更快?

转载 作者:IT王子 更新时间:2023-10-29 08:00:30 37 4
gpt4 key购买 nike

当需要过滤 NSArray 以获取返回数组中项目的子集时,哪种方法更频繁且在边缘情况下更快?

最佳答案

以下测试(在 Release 模式下编译,在 Mac Pro 上执行)表明如果您使用 filteredArrayUsingPredicateindexesOfObjectsPassingTest 慢一个“文本”谓词,但如果您使用基于 block 的谓词会更快。我测试中的 fasted 方法是一个简单的(快速枚举)循环,它添加了所有匹配项对象到可变数组。

过滤包含 10,000,000 个字典的数组的结果,其中约 50% 与谓词匹配:

8.514334 (predicateWithFormat)4.422550 (predicateWithBlock)5.170086 (indexesOfObjectsPassingTest)3.154015 (fast-enumeration + mutable array)

Of course the results may be different for other predicates.

#import <Foundation/Foundation.h>

NSUInteger filter1(NSArray *a)
{
NSPredicate *pred = [NSPredicate predicateWithFormat:@"num > 1000 AND foo == 'bar'"];
NSArray *filtered = [a filteredArrayUsingPredicate:pred];
return [filtered count];
}

NSUInteger filter2(NSArray *a)
{
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(NSDictionary *obj, NSDictionary *bindings) {
return ([obj[@"num"] intValue] > 1000 && [obj[@"foo"] isEqualToString:@"bar"]);
}];
NSArray *filtered = [a filteredArrayUsingPredicate:pred];
return [filtered count];
}

NSUInteger filter3(NSArray *a)
{
NSIndexSet *matching = [a indexesOfObjectsPassingTest:^BOOL(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
return ([obj[@"num"] intValue] > 1000 && [obj[@"foo"] isEqualToString:@"bar"]);
}];
NSArray *filtered = [a objectsAtIndexes:matching];
return [filtered count];
}

NSUInteger filter4(NSArray *a)
{
NSMutableArray *filtered = [NSMutableArray array];
for (NSDictionary *obj in a) {
if ([obj[@"num"] intValue] > 1000 && [obj[@"foo"] isEqualToString:@"bar"]) {
[filtered addObject:obj];
}
}
return [filtered count];
}

void testmethod(NSArray *a, NSUInteger(*method)(NSArray *a))
{
@autoreleasepool {
NSDate *t1 = [NSDate date];
NSUInteger count = method(a);
NSDate *t2 = [NSDate date];
NSLog(@"%f", [t2 timeIntervalSinceDate:t1]);
}
}

int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableArray *a = [NSMutableArray array];
for (int i = 0; i < 10000000; i++) {
[a addObject:@{@"num": @(arc4random_uniform(2000)), @"foo":@"bar"}];
}
testmethod(a, filter1);
testmethod(a, filter2);
testmethod(a, filter3);
testmethod(a, filter4);
}
return 0;
}

关于ios - indexOfObjectsPassingTest 或 filteredArrayUsingPredicate 哪个性能更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21157109/

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