在 NSNumbers 的 NSArray 中查找最小值和最大值 [英] Finding smallest and biggest value in NSArray of NSNumbers

查看:31
本文介绍了在 NSNumbers 的 NSArray 中查找最小值和最大值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

floats 中比较包含 NSNumbersNSArray 的所有值以找到最大和最小的值是什么有效且好方法一个?

有什么想法可以在 Objective-C 中快速高效地做到这一点吗?

解决方案

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

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

NSArray *sorted1 = [numbers sortedArrayUsingSelector:@selector(compare:)];//1.585 秒

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

NSNumber *max=[numbers valueForKeyPath:@"@max.doubleValue"];NSNumber *min=[numbers valueForKeyPath:@"@min.doubleValue"];//0.778 秒

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

NSNumber *max=[numbers valueForKeyPath:@"@max.self"];NSNumber *min=[numbers valueForKeyPath:@"@min.self"];//0.390 秒

版本 4:显式循环:

float xmax = -MAXFLOAT;浮动 xmin = MAXFLOAT;for (NSNumber *num in numbers) {浮动 x = num.floatValue;如果 (x  xmax) xmax = x;}//0.019 秒

版本 5:块枚举:

__block float xmax = -MAXFLOAT;__block float xmin = MAXFLOAT;[numbers enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {浮动 x = num.floatValue;如果 (x  xmax) xmax = x;}];//0.024 秒

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

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

<前>排序 1.404KVO1 1.087KVO2 0.367快速枚举 0.017块枚举 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;身份锁;[numbers enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {浮动 x = num.floatValue;@同步(锁定){如果 (x  xmax) xmax = x;}}];

这里的时间是

<前>并发枚举 0.009

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

What's an effective and great way to compare all the values of NSArray that contains NSNumbers from floats to find the biggest one and the smallest one?

Any ideas how to do this nice and quick in Objective-C?

解决方案

If execution speed (not programming speed) is important, then an explicit loop is the fastest. I made the following tests with an array of 1000000 random numbers:

Version 1: sort the array:

NSArray *sorted1 = [numbers sortedArrayUsingSelector:@selector(compare:)];
// 1.585 seconds

Version 2: Key-value coding, using "doubleValue":

NSNumber *max=[numbers valueForKeyPath:@"@max.doubleValue"];
NSNumber *min=[numbers valueForKeyPath:@"@min.doubleValue"];
// 0.778 seconds

Version 3: Key-value coding, using "self":

NSNumber *max=[numbers valueForKeyPath:@"@max.self"];
NSNumber *min=[numbers valueForKeyPath:@"@min.self"];
// 0.390 seconds

Version 4: Explicit loop:

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

Version 5: Block enumeration:

__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

The test program creates an array of 1000000 random numbers and then applies all sorting techniques to the same array. The timings above are the output of one run, but I make about 20 runs with very similar results in each run. I also changed the order in which the 5 sorting methods are applied to exclude caching effects.

Update: I have now created a (hopefully) better test program. The full source code is here: https://gist.github.com/anonymous/5356982. The average times for sorting an array of 1000000 random numbers are (in seconds, on an 3.1 GHz Core i5 iMac, release compile):

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

Update 2: As one can see, fast enumeration is faster than block enumeration (which is also stated here: http://blog.bignerdranch.com/2337-incremental-arrayification/).

EDIT: The following is completely wrong, because I forgot to initialize the object used as lock, as Hot Licks correctly noticed, so that no synchronization is done at all. And with lock = [[NSObject alloc] init]; the concurrent enumeration is so slow that I dare not to show the result. Perhaps a faster synchronization mechanism might help ...)

This changes dramatically if you add the NSEnumerationConcurrent option to the block enumeration:

__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;
    }
}];

The timing here is

Concurrent enum  0.009

so it is about twice as fast as fast enumeration. The result is probably not representative because it depends on the number of threads available. But interesting anyway! Note that I have used the "easiest-to-use" synchronization method, which might not be the fastest.

这篇关于在 NSNumbers 的 NSArray 中查找最小值和最大值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆