パフォーマンスに関心がある人のために、XCTest フレームワークのmeasureBlock
API を使用して、Swift で簡単なテストを実行しました。簡単に言えば、ループで呼び出すと、違いが大きくなります。
テストに使用するコードは次のとおりです。
public protocol MyTestClassDelegate: class {
func myTestDelegateCallback()
}
public let TestClassValueChangedNotification = "TestClassNotification"
public class MyViewModel {
public weak var delegate: MyTestClassDelegate?
public init() { }
public func doNotification() {
NSNotificationCenter.defaultCenter().postNotificationName(TestClassValueChangedNotification, object: nil)
}
public func doDelegation(value: Int) {
delegate?.myTestClassDelegateCallback()
}
}
そしてテストケース:
func testPerformanceNotifiction() {
measureBlock { () -> Void in
let testClass = MyTestClass()
for i in 0...100000 {
testClass.doNotification(i)
}
}
}
func testPerformanceDelegation() {
measureBlock { () -> Void in
let testClass = MyTestClass()
testClass.delegate = self
for i in 0...100000 {
testClass.doDelegation(i)
}
}
}
結果:
- 委任:- - - - - - 0.957 秒
- 通知センター: - 3.882 秒
私が試したくだらない代替案
その他の考慮事項として、NSNotificationCenter のパフォーマンスは、特定のイベントに対して存在するリスナーの数と、それらのリスナーによって実行されるコードのパフォーマンスによって明らかに異なる可能性があるということがあります。また、NSNotificationCenter が通知リスナーを同期的にpostNotification
呼び出し、呼び出されたのと同じスレッドで呼び出すことも注目に値します。これは、最初に NSNotificationCenter に近づくときに落とし穴になる可能性があります。
(私が経験したように) 1 対多の通信と高いパフォーマンスが必要なシナリオにいる場合は、単にデリゲートの配列を実装することを検討してください。しかし、これのパフォーマンスは実際には最悪のオプションであるため、気にする必要はありません。
public func doMultipleDelegatation() {
for i in 0..<delegates.count {
delegates[i].myTestDelegateCallback()
})
}
func testPerformanceMultipleDelegation() {
measureBlock { () -> Void in
let testClass = MyTestClass()
testClass.delegates = [self]
for i in 0...100000 {
testClass.doMultipleDelegation(i)
}
}
}
最終結果:
- 委任:- - - - - - 0.957 秒
- 通知センター: - 3.882 秒
- 複数の委任: - 6.488 秒