Actor Hop이란?

Ios_Roy·2025년 9월 15일

라이브러리 개발

목록 보기
5/25
post-thumbnail

Actor Hop은 Swift Concurrency에서 실행 컨텍스트가 한 Actor에서 다른 Actor로 전환되는 현상을 말합니다. 이는 성능에 영향을 미치는 중요한 개념입니다.

🎯 핵심 개념

Actor는 Swift의 동시성 모델에서 데이터 경쟁(data race)을 방지하기 위해 도입된 참조 타입입니다. 각 Actor는 자신만의 격리된 실행 컨텍스트를 가지며, 한 번에 하나의 작업만 실행할 수 있습니다.

🔄 Actor Hop 발생 상황

// Actor A
actor DatabaseActor {
    func fetchData() async -> String {
        // 데이터베이스 작업
        return "data"
    }
}

// Actor B (MainActor)
@MainActor
class ViewController {
    let database = DatabaseActor()
    
    func loadData() async {
        // 🔴 Hop 1: MainActor → DatabaseActor
        let data = await database.fetchData()
        
        // 🔴 Hop 2: DatabaseActor → MainActor (자동으로 돌아옴)
        updateUI(data)
    }
    
    func updateUI(_ data: String) {
        // UI 업데이트
    }
}

📊 Actor Hop의 비용

각 Actor Hop마다 발생하는 오버헤드:

  • 컨텍스트 스위칭: 0.1~0.3ms
  • 스케줄링 지연: Task가 다른 Actor의 큐로 이동
  • 메모리 동기화: Actor 간 데이터 전달

🔍 실제 예제로 이해하기

1. 많은 Actor Hop이 발생하는 경우

@MainActor
class BadExample {
    let service = NetworkService()      // 다른 Actor
    let database = DatabaseActor()      // 또 다른 Actor
    let cache = CacheActor()            // 또 다른 Actor
    
    func complexOperation() async {
        // 🔴 Hop 1: Main → NetworkService
        let data = await service.fetchData()
        
        // 🔴 Hop 2: NetworkService → DatabaseActor
        await database.save(data)
        
        // 🔴 Hop 3: DatabaseActor → CacheActor
        await cache.store(data)
        
        // 🔴 Hop 4: CacheActor → MainActor
        updateUI()
    }
    // 총 4번의 Actor Hop = 약 0.4~1.2ms 오버헤드
}

2. Actor Hop을 최소화한 경우

@MainActor
class GoodExample {
    let dataService = DataService() // 모든 작업을 처리하는 단일 Actor
    
    func optimizedOperation() async {
        // 🟢 Hop 1: Main → DataService (한 번만!)
        let result = await dataService.performAllOperations()
        
        // 🟢 Hop 2: DataService → Main (자동 복귀)
        updateUI(result)
    }
    // 총 2번의 Actor Hop = 약 0.2~0.6ms 오버헤드
}

🎬 시각적 비유

Actor Hop을 현실 세계에 비유하면:

🏢 건물 A (MainActor)     🏢 건물 B (DatabaseActor)     🏢 건물 C (NetworkActor)
     │                           │                            │
     │  📦 작업 요청 →          │                            │
     │  (이동 시간 소요)        │                            │
     │                           │  📦 작업 요청 →            │
     │                           │  (이동 시간 소요)         │
     │                           │                            │
     │                           │  ← 📦 결과 반환           │
     │  ← 📦 결과 반환          │                            │

각 건물 간 이동(Hop)마다 시간이 소요됩니다.

⚡ Actor Hop이 성능에 미치는 영향

// 성능 측정 예제
func measureActorHops() async {
    let startTime = CFAbsoluteTimeGetCurrent()
    
    // 100번의 Actor Hop 발생
    for _ in 0..<100 {
        await someActor.doWork()
    }
    
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print("Time: \(timeElapsed)초")
    // 결과: 약 10~30ms (Actor Hop 오버헤드만!)
}

🛠 Actor Hop 최적화 전략

1. 배치 처리

// ❌ 나쁜 예: 여러 번의 Hop
for item in items {
    await actor.process(item)  // 각각 Hop 발생
}

// ✅ 좋은 예: 한 번의 Hop
await actor.processAll(items)  // 한 번만 Hop

2. 같은 Actor에서 작업 그룹화

actor DataProcessor {
    // 여러 작업을 한 번에 처리
    func processMultiple() async -> ProcessResult {
        let fetched = await fetchInternal()
        let transformed = transform(fetched)
        let validated = validate(transformed)
        return ProcessResult(validated)
    }
}

3. nonisolated 사용

actor MyActor {
    // Actor Hop이 발생하지 않음
    nonisolated func getSyncData() -> String {
        return "data"  // 동기적으로 즉시 반환
    }
}

📈 DiContainer의 Actor Hop 최적화

DiContainer 2.0에서는 이러한 Actor Hop을 지능적으로 최소화합니다:

// DiContainer의 최적화된 접근
@MainActor
class OptimizedViewController {
    @Inject var userService: UserService
    
    func loadData() async {
        // DiContainer가 Actor 컨텍스트를 추적하여
        // 불필요한 Hop을 방지
        let data = await userService.fetchUser()
        updateUI(data)  // 이미 MainActor 컨텍스트
    }
}

이렇게 Actor Hop을 이해하고 최적화하면 Swift Concurrency 환경에서 훨씬 더 효율적인 코드를 작성할 수 있습니다! 🚀

profile
iOS 개발자 공부하는 Roy

0개의 댓글