0

I'm processing ~10k events between two different classes. One is fetching them, and the other is storing them in a dictionary. Now since the fetching class is also doing more stuff with the data than just passing it to the second class, it really doesn't make a lot of sense to send them over as a big bulk, but rather I'm processing them like

actor Fetcher {
  let someProcessor = Processor()

  func getData() async {
    let results = await Rest.getData()
    for result in results {
      await someProcessor.doStuff(with: result)
      await someOtherObject.handle(result)
    }
  }
}

actor Processor {
  func doStuff(with result: Result) async {
    // ...
  }
}

now maybe you can see the problem. With both of them being actors, I keep sending around data between threads. Processing ~10k results thus takes 8 seconds. This is mostly because of thread switches. If I make my code non-thread-safe by removing the actor keyword it takes less than a second. It would remove some functionality of my code if I did that though. Is there a way to tell swift that these two actors should always run in the same Thread to avoid the switching?

6
  • 4
    Actors are not directly related to threads, actors run on actors and different actors run on different ones. A TaskGroup would likely help you maximize time. Commented Jan 25, 2023 at 1:40
  • See AsyncChannel (github.com/apple/swift-async-algorithms/blob/main/Sources/…). You can let Processor and someOtherObject communicate without needing to switch to Fetcher's context (but still without them knowing each other). doStuff will asynchronously return a stream of values that handle will consume. Commented Jan 25, 2023 at 3:20
  • There’s not enough here for us to advise you, but doing 10k synchronizations will likely be much slower than one big synchronization. And it seems like there is an opportunity to enjoy some parallelism with task groups, but it’s hard to advise you without more details and or a reproducible example. But right now you have tons of suspension points and no parallelism. Commented Jan 25, 2023 at 5:24
  • By the way, if you are interested in better understanding the Swift concurrency threading model, see WWDC 2021 video Swift concurrency: Behind the scenes. As you'll see there, Swift concurrency system is quite clever about minimizing costly thread switches. The problem is unlikely to be related to thread switches, but rather all of these suspension points. Commented Jan 25, 2023 at 19:54
  • thanks for the feedback. how would you reduce suspension points in the above code @Rob? Commented Jan 26, 2023 at 4:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.