티스토리 뷰

반응형

 

안녕하세요~ 개발자 멍구입니다! 오늘은 Swift6, Swift concurrency 런타임 동작 관련 내용을 번역한 내용을 정리해서 공유드립니다.

 

 


Swift Concurrency, 런타임 동작(Runtime Behavior)

Swift의 동시성 모델은 async/await, actor, task 등에 초점을 맞추고 있습니다. 기존의 동시성 라이브러리나 런타임이 Swift의 새로운 동시성 모델로 직접 변환되지 않을 수도 있습니다. 이번 글에서는 런타임 동작에서 주의해야 할 공통 패턴과 차이점을 살펴보고, 기존 코드를 Swift Concurrency로 마이그레이션할 때 이를 어떻게 해결할 수 있는지 알아보겠습니다.


Task Group을 사용한 동시성 제한

많은 양의 작업을 처리해야 하는 상황에서 아래와 같이 모든 작업을 한꺼번에 Task Group에 추가해서 작업을 수행할 수 있습니다.

// 비효율적인 방식: 수천 개의 작업이 한꺼번에 생성될 가능성이 있음let lotsOfWork: [Work] = ...
await withTaskGroup(of: Something.self) { group in
  for work in lotsOfWork {
    // 만약 작업 항목이 수천 개라면, 많은 수의 작업이 한꺼번에 생성됨
    group.addTask {
      await work.work()
    }
  }
​
  for await result in group {
    process(result) // 작업 결과 처리
  }
}

위 방식처럼 수백~수천 개의 작업을 한 번에 Task Group에 추가하는 것은 비효율적일 수 있습니다. addTask를 호출하면 작업을 일시 중단하고 실행할 수 있도록 메모리를 할당하게 됩니다. 개별 작업이 차지하는 메모리는 크지 않더라도, 즉시 실행되지 않는 수천 개의 작업이 쌓이면 상당한 메모리 사용을 초래할 수 있습니다.

해결 방법: 작업 수 제한 (Throttling)

이러한 문제를 해결하기 위해, 동시에 추가할 작업 수를 제한하는 방식으로 수동 조절(throttling)할 수 있습니다.

let lotsOfWork: [Work] = ...
// 최대 동시 실행 작업 수를 10개로 제한
let maxConcurrentWorkTasks = min(lotsOfWork.count, 10)
assert(maxConcurrentWorkTasks > 0)
​
await withTaskGroup(of: Something.self) { group in
    var submittedWork = 0
    
    // 초기 작업 추가 (최대 10개)
    for _ in 0..<maxConcurrentWorkTasks {
        group.addTask { // 'addTaskUnlessCancelled'를 사용할 수도 있음
            await lotsOfWork[submittedWork].work()
        }
        submittedWork += 1
    }
    
    for await result in group {
        process(result) // 작업 결과 처리
​
        // 새로운 결과가 도착할 때마다 추가 작업 실행
        if submittedWork < lotsOfWork.count,
           let remainingWorkItem = lotsOfWork[submittedWork] {
            group.addTask { // 'addTaskUnlessCancelled'를 사용할 수도 있음
                await remainingWorkItem.work()
            }  
            submittedWork += 1
        }
    }
}

이 방식에서는 한 번에 최대 10개의 작업만 실행되며, 새로운 작업 결과가 도착할 때마다 추가 작업이 실행됩니다. 이를 통해 과도한 메모리 사용을 방지하면서도 효율적으로 동시성을 조절할 수 있습니다.


결론

Swift Concurrency에서는 무분별한 태스크 생성이 메모리 사용량 증가로 이어질 수 있습니다. 따라서 Task Group을 사용할 때는 작업의 특성을 고려하여 적절한 동시 실행 수를 제한하는 것이 중요합니다.

위와 같은 throttling 기법을 적용하면 보다 효율적인 동시성 관리를 할 수 있습니다. Swift 동시성을 활용하는 코드에서 최적의 성능을 내기 위해서는 이러한 최적화 기법을 적극적으로 활용하는 것이 좋습니다.

 


Swift Concurrency 개념 중 하나인 Task Group 활용을 할때, 수백, 수천 개의 작업이 수행될 가능성이 있는지 판단하고, 필요에 따라 위와 같은 Throttling 기법을 활용해볼 수도 있겠습니다! 

 

 

 

Documentation

 

www.swift.org

 

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함