我有一个填充数组的方法,但是里面的计算非常大而且很慢,我想使用多线程来加速它。
unsigned char array[500*500*4];
for(int i=0; i<500; i++) {
for(int j=0; j<500; j++) {
CGFloat element = [self veryLongCalculationWithI:i andJ:j];
array[k] = drand48()*255;
array[k+1] = drand48()*255;
array[k+2] = drand48()*255;
array[k+3] = element*255;
k+=4;
}
}
我该怎么做?我一直在调查GDC与调度异步,但我不确定这是否是最佳方式。有什么建议吗?
答案 0 :(得分:0)
帮助并行化计算的一个解决方案是使用并发NSOperationQueue
。
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// Be sure to call free() on array when appropriate
unsigned char *array = calloc(500 * 500 * 4, sizeof(unsigned char));
int k = 0;
for (int i = 0; i < 500; i++) {
for (int j = 0; j < 500; j++) {
[queue addOperationWithBlock:^{
CGFloat element = [self veryLongCalculationWithI:i andJ:j];
array[k + 3] = element * 255;
}];
[queue addOperationWithBlock:^{
array[k] = drand48() * 255;
array[k + 1] = drand48() * 255;
array[k + 2] = drand48() * 255;
}];
k += 4;
}
}
// optional, if needed:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[queue waitUntilAllOperationsAreFinished];
dispatch_async(dispatch_get_main_queue(). ^{
// Update UI as needed
});
});
以上是打破它的一种可能方法。尝试一些变化并做一些时间测试。另请注意,结果取决于设备及其拥有的核心数。
更新 - 上述代码最终创建了500,000个操作。该开销可能比原始代码更糟糕。尝试这样的事情:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// Be sure to call free() on array when appropriate
unsigned char *array = calloc(500 * 500 * 4, sizeof(unsigned char));
int k = 0;
for (int i = 0; i < 500; i++) {
[queue addOperationWithBlock:^{
for (int j = 0; j < 500; j++) {
CGFloat element = [self veryLongCalculationWithI:i andJ:j];
array[k + 3] = element * 255;
array[k] = drand48() * 255;
array[k + 1] = drand48() * 255;
array[k + 2] = drand48() * 255;
k += 4;
}
}];
}
// optional, if needed:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[queue waitUntilAllOperationsAreFinished];
dispatch_async(dispatch_get_main_queue(). ^{
// Update UI as needed
});
});
答案 1 :(得分:-1)
我们在swift中有GCD的一般语法 在后台进行计算并更新前景中的UI
BASIC SYNTAX
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
// do background task
dispatch_async(dispatch_get_main_queue()) {
// update some UI
}
}
将所有计算代码保留在后台任务中。这不会阻止您的用户界面。