使用 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 数组进行排序