且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在NSNumbers的NSArray中寻找最小和最大值

更新时间:2023-02-04 08:44:31

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

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:

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

Version 1: sort the array:

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

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

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

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

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

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

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

第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

版本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

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

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.

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

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

更新2:正如人们所看到的,快速枚举比块枚举快(在此处也进行了说明:

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/).

编辑:以下是完全错误的,因为正如Hot Licks正确地注意到的那样,我忘记了初始化用作锁的对象,因此根本不进行同步. 使用lock = [[NSObject alloc] init];时,并发枚举如此之慢 我不敢显示结果.也许更快的同步机制可能 帮助...)

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 ...)

如果将NSEnumerationConcurrent选项添加到 块枚举:

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

这里的时间是


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.