4

今天早上,我偶然发现了这个线程为什么处理排序数组比处理未排序数组更快?发现它真的很有趣!

我想在 Objective-C 中尝试一下,在实现它时,我遇到了对整数数组进行排序的问题。因此下面的问题。

让我们考虑一个arraySize整数数组,用 0 到 256 之间的随机值初始化:

int data[arraySize];
for (int c = 0; c < arraySize; ++c)
{
    data[c] = arc4random() % 256;
}

我想对该数组进行排序并将结果存储在另一个整数数组中。在 C++ 中,我们可以这样做:

std::sort(data, ...);

在 Java 中,我们会使用:

Arrays.sort(data);

在 Objective-C 中,我是这样做的:

int sortedData[arraySize];
NSArray* sortedArray = [NSArray array];
// Initialize the array to sort.
for ( int i = 0 ; i < arraySize ; ++i )
{
    sortedArray = [sortedArray arrayByAddingObject:[NSNumber numberWithInt:data[i]]];
}
// Sort the array.
sortedArray = [sortedArray sortedArrayUsingSelector:@selector(compare:)];
// Copy the array back into a int[] array.
for (int c = 0; c < arraySize; ++c)
{
    sortedData[c] = [sortedArray[c] intValue];
}

它有效,但在我看来这是一个真正的痛苦,它根本没有优化!我该如何改进呢?

4

3 回答 3

8

“未优化”声明仅适用于您拥有的代码。苹果的框架是高度优化的,你不应该第二次猜测苹果,他们已经第二次猜测你了。

首先,将方法用于创建它们的目的。您创建未排序数组的方式只会浪费内存。在循环的每一步中,您都在创建一个新的数组实例,最后,您将得到 256 个(或任何原始整数数组的计数)数组,这只是多余的。

所以,如果你真的非常想使用 Objective-C 来解决这个问题,你可以使用一个可变数组,你只需要一个NSMutableArray

int array[256];
// populate the C array here

NSMutableArray *objcArray = [NSMutableArray array];
for (int i = 0; i < sizeof(array) / sizeof(*array); i++) {
    [objcArray addObject:[NSNumber numberWithInt:array[i]];
}

[objcArray sortUsingSelector:@selector(compare:)];

顺便说一句,NSMutableArray这里甚至不需要两个循环(一个用于填充 C 数组,一个用于将其转换为 )。你可以写

const size_t size = 256;
NSMutableArray *objcArray = [NSMutableArray array];
for (int i = 0; i < size; i++) {
    [objcArray addObject:[NSNumber numberWithInt:arc4random_uniform(256)];
}

[objcArray sortUsingSelector:@selector(compare:)];

但是,您实际上并不需要 Objective-C 来对整数数组进行排序。您可以简单地编写一个 C 函数(或者,如果需要,一个 Objective-C 方法)来对整数数组进行就地排序,这可能会更有效或更快:

#include <math.h>
#include <stdlib.h>
#include <unistd.h>

int compare(const void *first, const void *second)
{
    return *(const int *)first - *(const int *)second;
}

- (void)sortArray:(int *)array ofSize:(size_t)sz
{
    qsort(array, sz, sizeof(*array), compare);
}

然后像这样使用它:

int array[256];
for (int i = 0; i < sizeof(array) / sizeof(*array); i++) {
    array[i] = arc4random_uniform(256);
}

[self sortArray:array ofSize:sizeof(array) / sizeof(*array)];

另外,请阅读有关数组的内容。真是好文章。

于 2012-11-02T11:01:25.467 回答
0

使用 NSSortDescriptor 怎么样?

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"propertieToSort" ascending:NO];
NSArray *descArray = [NSArray arrayWithObject:dateDescriptor];
representedItems = [unsortedItems sortedArrayUsingDescriptors:descArray];

我不是 100% 确定这将适用于非 NSObjects,但我发誓我曾经使用过它。

于 2012-11-02T11:04:07.500 回答
0

您可以在 obj-c 项目中使用 c++,只需将文件重命名为 .mm 并添加#include <算法> 以使用 std.sort。我认为,将 NSNumber 用于 int 数据会更快

于 2012-11-02T11:04:27.423 回答