在NSNrray的NSNrray中找到最小和最大的值

Ser*_*yov 47 cocoa-touch objective-c nsarray ios

什么是比较所有值的有效和伟大的方式NSArray,包含NSNumbersfloats找到的最大一个和最小的一个?

任何想法如何在Objective-C中做到这一点好看又快?

Mar*_*n R 141

如果执行速度(不是编程速度)很重要,那么显式循环是最快的.我用1000000个随机数的数组进行了以下测试:

版本1:对数组进行排序:

NSArray *sorted1 = [numbers sortedArrayUsingSelector:@selector(compare:)];
// 1.585 seconds
Run Code Online (Sandbox Code Playgroud)

版本2:键值编码,使用"doubleValue":

NSNumber *max=[numbers valueForKeyPath:@"@max.doubleValue"];
NSNumber *min=[numbers valueForKeyPath:@"@min.doubleValue"];
// 0.778 seconds
Run Code Online (Sandbox Code Playgroud)

版本3:键值编码,使用"自我":

NSNumber *max=[numbers valueForKeyPath:@"@max.self"];
NSNumber *min=[numbers valueForKeyPath:@"@min.self"];
// 0.390 seconds
Run Code Online (Sandbox Code Playgroud)

版本4:显式循环:

float xmax = -MAXFLOAT;
float xmin = MAXFLOAT;
for (NSNumber *num in numbers) {
    float x = num.floatValue;
    if (x < xmin) xmin = x;
    if (x > xmax) xmax = x;
}
// 0.019 seconds
Run Code Online (Sandbox Code Playgroud)

版本5:块枚举:

__block float xmax = -MAXFLOAT;
__block float xmin = MAXFLOAT;
[numbers enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
    float x = num.floatValue;
    if (x < xmin) xmin = x;
    if (x > xmax) xmax = x;
}];
// 0.024 seconds
Run Code Online (Sandbox Code Playgroud)

测试程序创建一个包含1000000个随机数的数组,然后将所有排序技术应用于同一个数组.上面的时间是一次运行的输出,但我在每次运行中进行了大约20次运行,结果非常相似.我还更改了应用5种排序方法的顺序,以排除缓存效果.

更新:我现在已经创建了一个(希望)更好的测试程序.完整的源代码在这里:https://gist.github.com/anonymous/5356982.对1000000个随机数组进行排序的平均时间是(以秒为单位,在3.1 GHz Core i5 iMac上,发布编译):

Sorting      1.404
KVO1         1.087
KVO2         0.367
Fast enum    0.017
Block enum   0.021

更新2:可以看出,快速枚举比块枚举更快(这里也说明了这一点:http://blog.bignerdranch.com/2337-incremental-arrayification/).

编辑:以下是完全错误的,因为我忘了初始化用作锁的对象,因为Hot Licks正确注意到,因此根本没有完成同步.而且随着lock = [[NSObject alloc] init];并发枚举这么慢 ,我不敢来显示结果.也许更快的同步机制可能会有所帮助...)

如果将NSEnumerationConcurrent选项添加到块枚举,则会发生显着变化:

__block float xmax = -MAXFLOAT;
__block float xmin = MAXFLOAT;
id lock;
[numbers enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
    float x = num.floatValue;
    @synchronized(lock) {
        if (x < xmin) xmin = x;
        if (x > xmax) xmax = x;
    }
}];
Run Code Online (Sandbox Code Playgroud)

这里的时间是

Concurrent enum  0.009

所以它的速度大约是快速枚举的两倍.结果可能不具代表性,因为它取决于可用线程的数量.但无论如何有趣!请注意,我使用了"最易于使用"的同步方法,该方法可能不是最快的.


Ano*_*dya 14

然后通过在NSNumber下包装来保存浮动

NSNumber *max=[numberArray valueForKeyPath:@"@max.doubleValue"];
NSNumber *min=[numberArray valueForKeyPath:@"@min.doubleValue"];
Run Code Online (Sandbox Code Playgroud)

*未编译和检查,已使用intValue检查,不确定double或float