I\'m building a physics engine in Swift. After making some recent additions to the engine and running the benchmarking tests I noticed the performance was drastically slower
As I was writing up/investigating this issue, I eventually found a solution. To have a simple back pointer without the overhead checks of weak
or unowned
you can declare body as:
unowned(unsafe) var body: Body!
According to the Swift documentation:
Swift also provides unsafe unowned references for cases where you need to disable runtime safety checks—for example, for performance reasons. As with all unsafe operations, you take on the responsibility for checking that code for safety.
You indicate an unsafe unowned reference by writing unowned(unsafe). If you try to access an unsafe unowned reference after the instance that it refers to is deallocated, your program will try to access the memory location where the instance used to be, which is an unsafe operation
So it is clear these runtime checks can produce serious overhead in performance-critical code.
Update:
As of Swift 5.2 (Xcode 11.4), I have noticed that unowned(unsafe)
has much more overhead. I now simply use strong references and break retain cycles manually, or try to avoid them entirely in performance-critical code.
Note: This is still true as of Xcode 12/Swift 5.3