Do we negate some performance improvements by using Reduce? #1363
Replies: 1 comment 1 reply
-
While When your reducer is run, under the hood the In such cases the compiler can see that the closure doesn't actually escape and so you do not incur a performance penalty. Here's a benchmark that does a really silly thing to build up a two large nested closures, one that does actually escape, and the other does not: struct Func<A> {
var run: (A) -> A
mutating func compose(with g: Self) {
let run = self.run
self.run = { g.run(run($0)) }
}
}
let incr = Func<Int> { $0 + 1 }
var add20 = incr
for _ in 1...19 {
add20.compose(with: incr)
}
benchmark("Actually escaping") {
precondition(add20.run(1) == 21)
}
benchmark("Not actually escaping") {
let incr = Func<Int> { $0 + 1 }
var add20 = incr
for _ in 1...19 {
add20.compose(with: incr)
}
precondition(add20.run(1) == 21)
} The results show that we did not incur a cost for the not-actually-escaping closure:
|
Beta Was this translation helpful? Give feedback.
-
As I understand from the migration guide, we use
reduce(into:action:)
only on the leaf nodes, and usevar body: some ReducerProtocol<State, Action>
for other reducers.However, I thought we moved from closures to protocols because it helped the compiler inline the calls, but now we pass a closure to Reduce so aren't we in the same place as before? Especially that most of the reducers in the app will not be leaf reducers.
This is the kind of code I'm talking about.
Beta Was this translation helpful? Give feedback.
All reactions