-
Notifications
You must be signed in to change notification settings - Fork 432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cutting the SignalProducer overhead further. #487
Changes from 13 commits
5cb7499
bbd8da3
997dd2e
0eaa0e2
c5ab301
8474282
58086db
5ce3c5a
ce3fe65
950d2a3
4bc0c81
54bf88f
b6bbb8a
748b4c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,31 @@ extension UnsafeAtomicState where State == DisposableState { | |
} | ||
} | ||
|
||
/// A disposable that does not have side effect upon disposal. | ||
internal final class _SimpleDisposable: Disposable { | ||
private let state = UnsafeAtomicState<DisposableState>(.active) | ||
|
||
var isDisposed: Bool { | ||
return state.is(.disposed) | ||
} | ||
|
||
func dispose() { | ||
_ = state.tryDispose() | ||
} | ||
|
||
deinit { | ||
state.deinitialize() | ||
} | ||
} | ||
|
||
/// A disposable that has already been disposed. | ||
internal final class NopDisposable: Disposable { | ||
static let shared = NopDisposable() | ||
var isDisposed = true | ||
func dispose() {} | ||
private init() {} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This breaks the contract of I think we'd be better off bringing back the implementation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we treat it as disposed then? It still makes sense for its use case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not bring back There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a shared disposable for constant producers that practically would never be disposed of, because they terminate before the disposable is returned. When I iterate on the design, benchmark shows allocation contributes considerable overhead over |
||
|
||
/// A type-erased disposable that forwards operations to an underlying disposable. | ||
public final class AnyDisposable: Disposable { | ||
private final class ActionDisposable: Disposable { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,24 @@ extension Signal { | |
/// Whether the observer should send an `interrupted` event as it deinitializes. | ||
private let interruptsOnDeinit: Bool | ||
|
||
/// The target observer of `self`. | ||
private let wrapped: AnyObject? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't love adding more to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sadly, we have to retain observers marked with // @testEventTransformingCoreMapFilter(): avg 6091 ns; min 5250 ns
self.action = transform(observer.action)
self.wrapped = observer
// @testEventTransformingCoreMapFilter(): avg 6238 ns; min 5402 ns
self.action = transform { observer.action($0) } |
||
|
||
/// An initializer that transforms the action of the given observer with the | ||
/// given transform. | ||
/// | ||
/// If the given observer would perform side effect on deinitialization, the | ||
/// created observer would retain it. | ||
/// | ||
/// - parameters: | ||
/// - observer: The observer to transform. | ||
/// - transform: The transform. | ||
internal init<U, E: Swift.Error>(_ observer: Signal<U, E>.Observer, _ transform: @escaping (@escaping Signal<U, E>.Observer.Action) -> Action) { | ||
self.action = transform(observer.action) | ||
self.wrapped = observer.interruptsOnDeinit ? observer : nil | ||
self.interruptsOnDeinit = false | ||
} | ||
|
||
/// An initializer that accepts a closure accepting an event for the | ||
/// observer. | ||
/// | ||
|
@@ -27,6 +45,7 @@ extension Signal { | |
/// event as it deinitializes. `false` otherwise. | ||
internal init(action: @escaping Action, interruptsOnDeinit: Bool) { | ||
self.action = action | ||
self.wrapped = nil | ||
self.interruptsOnDeinit = interruptsOnDeinit | ||
} | ||
|
||
|
@@ -37,6 +56,7 @@ extension Signal { | |
/// - action: A closure to lift over received event. | ||
public init(_ action: @escaping Action) { | ||
self.action = action | ||
self.wrapped = nil | ||
self.interruptsOnDeinit = false | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is duplicated in the 2.0.1 notes. 🙈