Replies: 4 comments 1 reply
-
I'm sharing some of my findings on the performance of the I did my own quick and dirty instrumentation using a DEBUG build (and without The table below shows the two use cases and how many times
From this simple use case, there is a lot of computation going on to perform the perception check. This results in a severe degradation in performance and explains why typing in a text field in the simulator is painfully slow with 0.75 seconds of computation per keystroke. The good news is the main culprit seems to be the unnecessary perception checks inside of reducers. Reducer call stack frames are particularly large and also have very complicated mangled names. So not only are they responsible for over 75% of the calls to Although this use case was a simple interactive UI use case, any heavy use of read access on observed state inside a reducer is going to incur a large penalty when running the perception back port in DEBUG mode due to the perception check. Since we don't care about read access of observed state in a reducer for the purpose of the perception check, it seems that there is some low hanging fruit to detect if Thoughts? Originally posted by @scogeo in #2594 (comment) |
Beta Was this translation helpful? Give feedback.
-
I did some more digging on the performance issue on DEBUG builds when using fileprivate var memoizedResults: [AnyHashable: Bool] = [:]
var isInSwiftUIBody: Bool {
// Check cache
let addresses = Thread.callStackReturnAddresses
if let memoizedResult = memoizedResults[addresses] {
return memoizedResult
}
for callStackSymbol in Thread.callStackSymbols {
guard
let symbol = callStackSymbol.split(separator: " ").dropFirst(3).first,
symbol.utf8.first == .init(ascii: "$"),
let demangled = String(symbol).demangled,
demangled.hasPrefix("protocol witness for SwiftUI.View.body.getter : ")
else { continue }
// update cache
memoizedResults[addresses] = true
return true
}
// update cache
memoizedResults[addresses] = false
return false
} This was just a quick hack to take a stab at the problem and doesn't take into account threading, etc. but there is clearly some room for improvement here. But with this quick hack I was able to at least fully exercise my app in the simulator when it was previously nearly unusable due to the lag. Originally posted by @scogeo in #2594 (reply in thread) |
Beta Was this translation helpful? Give feedback.
-
@mbrandonw I can put together a PR against the |
Beta Was this translation helpful? Give feedback.
-
Since I started this discussion, 3 PRs (#2622, #2630, and #2649) have been merged into the |
Beta Was this translation helpful? Give feedback.
-
Several of us have noticed performance issues when using the new Perception backport on iOS 16 or earlier. The performance issues seem to only affect DEBUG builds and can be traced down to frequent calls to
perceptionCheck()
which provides the purple runtime warnings in Xcode when perception is used incorrectly. This is an amazing diagnostic tool to have, but the current performance cost as implemented make is impracticable to use in complicated real world applications.I have done some experiments on this already and looked at a few options to improve performance including some type of memoization to cache the results of perception check calculations and eliminating perception checks when called from inside a reducer.
I will include copies of the above posts below.
Beta Was this translation helpful? Give feedback.
All reactions