티스토리 뷰
[iOS] DispatchQueue 알아보기 - SerialQueue, ConcurrentQueue, QoS, concurrentPerform
Kim_Baechu 2021. 1. 18. 21:53SerialQueue
순차 실행 작업을 계획합니다.
DispatchQueue의 attributes를 비워두면 serial이 됩니다.
let serialQueue = DispatchQueue(label: "serialQueue")
func serialQueueA() {
serialQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("❤️", i)
}
}
}
func serialQueueB() {
serialQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("💚", i)
}
}
}
serialQueueA()
serialQueueB()
serialQueue는 순차적으로 시행되므로 결과는 아래와 같습니다.
하나의 시리얼 큐를 더 만들어보겠습니다.
let serialQueue = DispatchQueue(label: "serialQueue")
let serialQueue2 = DispatchQueue(label: "serialQueue2")
func serialQueueA() {
serialQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("❤️", i)
}
}
}
func serialQueueB() {
serialQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("💚", i)
}
}
}
serialQueueA()
serialQueueB()
func serialQueueC() {
serialQueue2.async {
print(#function, Thread.current)
for i in 1...10 {
print("💛", i)
}
}
}
serialQueueC()
시리얼큐2는 첫 번째와 관련이 없습니다.
따라서 serialQueueA(), serialQueueB() 의 순서와 관계 없이 시행됩니다.
그리고 시리얼큐2는 다른 스레드에서 실행됩니다.
!! 테스트를 할 때, 항상 여러번 프린트해봐야합니다.
가끔 운좋게 모든 작업이 순차적으로 될 때도 있는데 항상 그렇다고 믿을 수 있기 때문입니다.
DispatchQoS.QoSClass
QoS는 다음과 같습니다.
userInteractive
- 시스템에서 가장 높은 우선순위, 애니메이션 UI등 사용자랑 상호작용
userInitiated
- 사용자가 앱을 액티브하게 사용하는 것을 막는 작업( prevent the user from actively using your app.)
- 사용자가 하는 작업에 대한 즉각적인 결과 제공
default
- 위 두 개보다 낮지만 utility나 background보다 높은 우선순위
utility
- default > utility > background
- 유저는 앱을 계속 사용가능
background
- 가장 낮은 우선순위
- 백그라운드에서 실행될때 작업 수행할 때 사용가능
테스트해볼까요?
let serialQueue = DispatchQueue(label: "serialQueue", qos: .userInteractive)
let serialQueue2 = DispatchQueue(label: "serialQueue2", qos: .default)
여러번 테스트해봤는데 노랑이 계속 더 늦게 끝납니다.
ConcurrentQueue
동시 실행 작업을 계획합니다.
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
func concurrentQueueA() {
concurrentQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("❤️", i)
}
}
}
func concurrentQueueB() {
concurrentQueue.async {
print(#function, Thread.current)
for i in 1...10 {
print("💛", i)
}
}
}
concurrentQueueA()
concurrentQueueB()
여러번 반복해보면 빨강이 먼저 끝나기도하고 노랑이 먼저 끝나기도합니다.
concurrentPerform(iterations:execute:)
싱글 블록을 디스패치 큐에 전달하고 iterations만큼 반복합니다.
이 메서드는 for루프를 효율적인 병렬 구현을 합니다.
var start = DispatchTime.now()
for i in 0..<100 {
print(i, terminator: " ")
}
var end = DispatchTime.now()
print("\n")
print("for loop :", start.distance(to: end))
print("\n")
//반복순서가 중요하지 않을 때 속도 개선가능
start = .now()
DispatchQueue.concurrentPerform(iterations: 100) { i in
print(i, terminator: " ")
}
end = .now()
print("\n")
print("concurrentPerform :", start.distance(to: end))
concurrentPerform은 자세히보면 숫자가 뒤죽박죽 되어있습니다.
for 루프에서보다 4배 이상 빠른 처리가 가능했습니다.
developer.apple.com/documentation/DISPATCH
'iOS' 카테고리의 다른 글
[iOS] Operation 알아보기 (0) | 2021.01.20 |
---|---|
[iOS] DispatchWorkItem, DispatchGroup 알아보기 (0) | 2021.01.18 |
[iOS] DispatchQueue 알아보기 (0) | 2021.01.18 |
[iOS] Dispatch 프레임워크 알아보기 (0) | 2021.01.18 |
[iOS] Customizing Collection View Layouts 알아보기 (0) | 2021.01.16 |