使用 Objective-C 对 int 数组进行排序 - 优化

Posted

技术标签:

【中文标题】使用 Objective-C 对 int 数组进行排序 - 优化【英文标题】:Sorting a array of int with Objective-C - Optimizing 【发布时间】:2012-10-23 00:34:11 【问题描述】:

今天早上,我偶然发现了这个帖子Why is it faster to process a sorted array than an unsorted array?,发现它真的很有趣!

我想在 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];

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

【问题讨论】:

【参考方案1】:

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

首先,将方法用于创建它们的目的。您创建未排序数组的方式只会浪费内存。在循环的每一步中,您都在创建一个新的数组实例,最后,您将得到 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:)];

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

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

另外,read this about arrays。真是好文章。

【讨论】:

不不,我成功使用了Objective-C,但是您的C代码示例非常完美,我将使用它!非常感谢! @AndyM 如果您觉得这个答案有用,请在可以的时候投票/接受,谢谢。 为什么你总是使用 "sizeof(array) / sizeof(*array)" 而不是数组大小的常数?它以任何方式更有效还是只是习惯?在您的 MutableArray 示例中,它会生成一个无限循环,不是吗?每次循环增加数组的大小... 实际上,在您的 MutableArray 示例上使用 sizeOf 时,我收到以下消息“在非脆弱 ABI 中将 'sizeof' 应用于接口 'NSMutableArray' 的无效应用”... @AndyM 两者都不是:它不是更有效,因为它与256 是同一种常量表达式,既不是“只是一种习惯”。使用它是因为如果您将数组大小从 256 更改为 128,它更不容易出错 - 在这种情况下,生成的程序将很好地发生段错误,这不是人们想要的。此外,在调整数组大小时不必重写所有大小更加优雅。出于类似的概念和面向良好实践的原因,我也不强制转换 malloc() 的返回值,将指针的星号写入变量名称而不是类型名称等。【参考方案2】:

使用 NSSortDescriptor 怎么样?

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于使用 Objective-C 对 int 数组进行排序 - 优化的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C 检查带有 int 的数组是不是包含 int [关闭]

在 Objective-C 中按评论数量对核心数据中的 FetchedObjects 数组进行排序

Objective-C - 使用 Accelerate.framework 对两个矩阵进行元素加法(和除法)

objective-c数组

关于objective-c数组,这些方法你得知道

仅使用 3 个元素对 int 数组进行排序