Fast threading in Swift

My app right now is very complex, and is very unoptimized for older devices. I have a complex UI with interactive elements, and an engine that runs stuff in the background, all on the same thread. As my app gets bigger an bigger, my old iPad keeps running it slower and slower. I thought threading it would help, but I read some tutorials and implented them. I put all of the engine stuff on the userInteractive thread, and kept all the UI stuff on the main thread. The speed did not improve, and the only change was the engine was running slower because it was on the less important thread.


I've worked a bit with threading in Java, and from my undestanding, you can create your own threads, which all run at the same speed. I cant seem to find anything like this in Swift, only the DispatchQueue.global.


Is there a way in Swift to have a complex engine (maybe an Engine class with all the necessary methods in it) on one thread, and a UI thread (possibly on main), so that they can improve the speed of the app, while still being able to communicate with one another (i.e. the engine can call methods that update the UI and vice versa)?

Accepted Reply

If you are targeting Cocoa/CocoaTouch, you can use dispatch queues, NSOperations, NSThreads, Posix threads(pthreads), Mach threads, and other technologies that are included as part of the Apple OS support for all it's devices. All are accessible from Swift.


If you are trying to be cross-platform, dispatch queues may be a possibility on Linux and other platforms, not sure since I only follow Linux Swift peripherally. You can always use pthreads from Swift as well.


As far as I know, native Swift support for threading (like Java) is on the to-do list, but, not actually sure if it will be in Swift 5.

Replies

If you are targeting Cocoa/CocoaTouch, you can use dispatch queues, NSOperations, NSThreads, Posix threads(pthreads), Mach threads, and other technologies that are included as part of the Apple OS support for all it's devices. All are accessible from Swift.


If you are trying to be cross-platform, dispatch queues may be a possibility on Linux and other platforms, not sure since I only follow Linux Swift peripherally. You can always use pthreads from Swift as well.


As far as I know, native Swift support for threading (like Java) is on the to-do list, but, not actually sure if it will be in Swift 5.

Thread will not speed up, but avoid latency due to blocked UI.


Maybe you should analyse your code with profiling tools.

If you are targeting Cocoa/CocoaTouch, you can use dispatch queues, NSOperations, NSThreads, Posix threads(pthreads), Mach threads, and other technologies that are included as part of the Apple OS support for all it's devices. All are accessible from Swift.

Two things:

  • These high-level technologies are not just available from Swift they have Swift-specific wrappers. For example,

    NSOperation
    maps to Swift’s
    Operation
    , and
    NSThread
    maps to
    Thread
    .
  • Creating Mach threads directly is not a realistic option.

As far as I know, native Swift support for threading (like Java) is on the to-do list, but, not actually sure if it will be in Swift 5.

There will definitely be no big changes with regards concurrency in Swift 5. If you’re curious about the high-level goals for Swift 5.0, see Swift 5.0 Release Process blog post.

There’s also no concrete plans for adding concurrency support in releases beyond Swift 5, but if you’re curious as to the direction that things might go you should check out the Swift Concurrency Manifesto.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Is there a way in Swift to have a complex engine … on one thread, and a UI thread …, so that they can improve the speed of the app, while still being able to communicate with one another (i.e. the engine can call methods that update the UI and vice versa)?

Yes, but Swift provides no automatic mechanism to do this. Rather, you have to use platform concurrency tools, like those mentioned by jonprescott, to coordinate this work. Lots of apps work this way, but it can be tricky to do properly.

The primary gotcha is mutable state. It’s not safe to shared mutable state between threads, so you have either protect your state using mutexes or isolate your state so that the state for a subsystem can only be accessed by the thread (or Dispatch serial queue) associated with that subsystem.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"