正如标题所示,NSOperationQueue 的 maxConcurrentOperationCount 的默认值是多少?
它是否设置为值 1?
正如标题所示,NSOperationQueue 的 maxConcurrentOperationCount 的默认值是多少?
它是否设置为值 1?
从文档中,
使用 setMaxConcurrentOperationCount: 方法在接收器上显式设置的最大并发操作数。如果没有显式设置值,则此方法默认返回 NSOperationQueueDefaultMaxConcurrentOperationCount。
所以它是NSOperationQueueDefaultMaxConcurrentOperationCount
。如果设置了此项,它将根据可用处理器的数量和其他相关因素选择适当的值。
这是它的定义方式:
enum {
NSOperationQueueDefaultMaxConcurrentOperationCount = -1
};
NSOperationQueueDefaultMaxConcurrentOperationCount:默认的最大操作数由 NSOperationQueue 对象根据当前系统条件动态确定。
在我的一个应用程序中,我一次添加了大约 35kNSOperation
个实例NSOperationQueue
。如果我设置maxConcurrentOperationCount
为 64,与默认值相比,我获得了大约 20 倍的性能。CPU 负载从 ~120% 上升到 400%,这似乎表明默认值太高以至于 CPU 主要忙于处理操作队列开销。
结论:如果你有很多短暂的生命NSOperation
,那么玩maxConcurrentOperationCount
.
maxConcurrentOperationCount
ofNSOperationQueue
在 iPhone 平台上只能设置为 1 到 6。maxConcurrentOperationCount
设置为NSOperationQueue
默认值不是一个好主意。因为这意味着无限数量的队列。
maxConcurrentOperationCount
ofNSOperationQueue
设置为 1 到 6 ?当可以同时调用多个任务时,maxConcurrentOperationCount
ofNSOperationQueue
应该设置为6。例如,可以同时下载多个图像。
为什么是 6 而不是 10 或 100?
在名为 的框架SDWebImage
中,我们可以看到源代码如下:
- (instancetype)init {
self = [super init];
if (self) {
_maxConcurrentDownloads = 6;
_downloadTimeout = 15.0;
_executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
_acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
}
return self;
}
此代码表示默认值为 6。 SDWebImage 参考 SDWebImageDownloaderConfig 类参考
的含义 maxConcurrentDownloads
与maxConcurrentOperationCount
(Apple-Docs-NSOperationQueue-maxConcurrentOperationCount)相同
为什么是 6 而不是 10 或 100?
SDWebImage
说它的编码器是通过实验:
参考:为什么 SDWebImageDownloader maxConcurrentOperationCount = 6?#1961
忽略实验, 从 iPhone 到 iPhone 13/13 Pro/13 Pro Max,iOS 平台上处理器核心的最大数量是 6 个,所以应该设置为 1 到 6 maxConcurrentOperationCount
。NSOperationQueue
苹果手机 | 首次发布 | 系统开启 | 处理器核心数 |
---|---|---|---|
苹果手机 | 2007年 | S (三星 S5L8900) | 1个核心 |
iPhone 3G | 2008年 | S (三星 S5L8900) | 1个核心 |
iPhone 3GS | 2009 | S(三星S5PC100 | 1个核心 |
iPhone 4 | 2010 | A4 | 1个核心 |
iPhone 4S | 2011 | A5 | 2个核心 |
iphone 5 | 2012 | A6 | 2个核心 |
iPhone 5S | 2013 | A7 | 2核 |
iPhone 6/6 加 | 2014 | A8 | 2个核心 |
iPhone 6s/6s plus/SE | 2015 | A9 | 2个核心 |
iPhone 7/加 | 2016 年 | A9 | 4核(使用2核) |
iPhone 8/加/X | 2017 | A11 | 6 个核心 = 2 个高功率 Monsoon 核心 + 4 个低功率 Mistral 核心 |
iPhone XS/XS MAX/XR | 2018 | A12 | 6 个核心 = 2 个高功率 Vortex 核心 + 4 个低功率 Tempest 核心 |
iPhone 11 /11 Pro/11 Pro Max | 2019 | A13 | 6 个核心 = 2 个性能 + 4 个效率核心 |
iPhone 12 /12 Pro/12 Pro Max | 2020 | A14 | 6 个核心 = 2 个性能 + 4 个效率核心 |
iPhone 13 /13 Pro/13 Pro Max | 2021 | A15 | 6 个核心 = 2 个性能 + 4 个效率核心 |
我们可以使用如下代码打印处理器内核的数量:
NSUInteger cpuCoresCount = [[NSProcessInfo processInfo] processorCount];
我们可以使用如下代码打印活动处理器内核的数量:
NSUInteger activeCPUCoresCount = [[NSProcessInfo processInfo] activeProcessorCount];
参考文档:Apple-Docs-NSProcessInfo-processorCount
_maxConcurrentDownloads
在 iPhone 平台上设置为 CPU 核心数是合理 的。至于进一步的评论,activeProcessorCount
可能会更好。
在名为 的框架中YYKit
,queueCount
设置为activeProcessorCount
.
#define MAX_QUEUE_COUNT 16
static int queueCount;
static dispatch_queue_t queues[MAX_QUEUE_COUNT];
static dispatch_once_t onceToken;
static int32_t counter = 0;
dispatch_once(&onceToken, ^{
queueCount = (int)[NSProcessInfo processInfo].activeProcessorCount;
queueCount = queueCount < 1 ? 1 : queueCount > MAX_QUEUE_COUNT ? MAX_QUEUE_COUNT : queueCount;
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
for (NSUInteger i = 0; i < queueCount; i++) {
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0);
queues[i] = dispatch_queue_create("com.ibireme.yykit.render", attr);
}
} else {
for (NSUInteger i = 0; i < queueCount; i++) {
queues[i] = dispatch_queue_create("com.ibireme.yykit.render", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(queues[i], dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
}
}
});
int32_t cur = OSAtomicIncrement32(&counter);
if (cur < 0) cur = -cur;
return queues[(cur) % queueCount];
#undef MAX_QUEUE_COUNT
maxConcurrentOperationCount
为NSOperationQueue
1 ?它们设置maxConcurrentOperationCount
为一个意味着只能同时调用一个任务。
当只能同时调用一个任务时, maxConcurrentOperationCount
应设置为1。例如,只能同时动画一张GIF图像;只能同时播放一个视频。此外,只能同时解码一个视频/图像。