NSNotificationCenter与委派 - 哪个更快?

时间:2013-07-29 10:04:31

标签: objective-c swift delegates nsnotificationcenter

我已经阅读了很多关于每个人的优点和缺点,我知道代表通常是一个听众,并且通知是针对很多人的。问题是关于绩效。

我读过这个:NSNotificationCenter vs delegation( using protocols )?

我正在通过通知将麦克风的音频信号发送到另一个班级。我知道在这里我应该使用代表但是我的问题是:代表会更快吗?因为我可以看到我有一些帧速率问题(减少),我想知道原因是否可以使用委托的通知代替,或者没有关系?

7 个答案:

答案 0 :(得分:27)

对于那些对性能感兴趣的人,我使用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时的问题。

如果您发现自己处于需要一对多通信和高性能的场景中,您可能会考虑简单地实现一组委托。但你不必费心,因为这样做的表现实际上是最糟糕的选择。

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秒

答案 1 :(得分:7)

代表的开销更少,因此执行速度更快。

但是,一般来说,您应该只考虑可能存在问题的性能主题。对于一次性任务,例如发送通知和调用委托,这应该永远不会成为问题。但是当你计划在一个带有变量(取决于数据)数量的循环中执行这些操作时,或者对于你已经获取或接收数据的许多数据对象,无法预测将会有多少 - 这些是在哪些情况下我会考虑性能优化。

答案 2 :(得分:1)

代表们更快。

录制时的帧速率问题不是由于代理或通知造成的。这是因为您正在主线程上执行所有任务,这也会呈现UI。

答案 3 :(得分:1)

NotificationCenter足够快。

首先,我测试了在主线程中发布和接收通知的同步情况,并将其与自我上的方法调用进行比较:

Method call: .036 ms
Notification: .13 ms

每个号码是100个电话中最差的情况。

由于即使在最坏的情况下通知速度也大约十分之一毫秒,因此它很可能足够快,除非您在没有任何其他重要计算的循环中运行它。

其次,我从后台队列发布了通知,并在主队列中收到通知,并将其与DispatchQueue进行比较:

Notification: 877 ms
DispatchQueue.sync: 871 ms
DispatchQueue.async: 867 ms

这里几乎没有区别。

方法:   - 发布模式  - iPhone 5S   - iOS 10.3.2。   - 无论他们从哪个线程发送请求,总是在主线程中处理请求。

答案 4 :(得分:0)

  

我知道在这里我应该使用代表但是我的问题是:是的   代表会更快?

很简单:尝试分享结果!

代理人在1:1时,点对点关系可以比任何系统中的1:m发布和订阅更快。

难以回答,因为它取决于环境。 什么时候不是很多听众而且出版商不需要为听众搜索很多,那么应该是类似的表现,但是当有一百万用户并且需要搜索它时,则可能是延迟,帧率下降。 / p>

答案 5 :(得分:0)

调用委托只是一个方法调用,但是当使用通知时,应该在幕后完成更多的工作来发送通知。考虑到这一点 - 委托更快一点。

实时音频处理是一项复杂的任务,我倾向于认为委托的方法调用或发送通知所产生的开销比音频处理代码少得多。

<强>更新

考虑到性能问题,您在尝试不同方法时应始终进行测量。

答案 6 :(得分:0)

代表会比通知更快,但不一定是您需要的。对于音频,你应该先测量一下。如果在更新UI之前需要更快地执行某些操作,那么您应该考虑通过GCD调度或NSOperation将一些处理任务移动到另一个线程。