swift NSNotificationCenter与委派-哪一个更快?

qcbq4gxm  于 2022-11-21  发布在  Swift
关注(0)|答案(7)|浏览(129)

我读过很多关于每种方法的优缺点的文章,我知道委托通常是针对一个侦听器的,而通知则是针对多个侦听器的。
我读过NSNotificationCenter vs delegation( using protocols )?
我正在通过通知将音频信号从麦克风发送到另一个班级。我知道在这里我应该使用代表,但我的问题是代表会更快吗?
我有一个降低帧速率的问题,我想知道的原因是否可能是使用通知而不是的委托,或没有关系?

ux6nzvsh

ux6nzvsh1#

对于那些对性能感兴趣的人,我使用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秒
  • 通知中心:- 三点八八二秒

我尝试过的蹩脚选择

其他注意事项是,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秒
  • 通知中心:- 三点八八二秒
  • 多重委派:- 六点四八八秒
bpsygsoo

bpsygsoo2#

委托的开销更少,因此执行速度更快。
然而,在一些情况下,一般来说,您应该只在性能主题可能成为问题的地方查看它们。对于一次性任务(如发送通知与调用委托),这永远不会成为问题。但是,当您计划在带有变量的循环中执行这些任务时(取决于数据)对于您已获取或接收数据的多个迭代或多个数据对象,无法预测将有多少-这些都是我会考虑性能优化的情况。

63lcw9qa

63lcw9qa3#

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

Method call: .036 ms
Notification: .13 ms

每个号码都是100个呼叫中的最坏情况。
由于即使在这种最坏的情况下,通知也要慢大约十分之一毫秒,所以它很可能已经足够快了,除非你在没有任何其他重要计算的循环中运行它。
第二,我从后台队列发布通知,并在主队列中接收它,将它与DispatchQueue进行比较:

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

在这里几乎没有区别。
方法学:- 发布模式-iPhone5s-iOS10.3.2。-请求总是在主线程中处理,无论它们是从哪个线程发出的。

x7yiwoj4

x7yiwoj44#

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

fdbelqdn

fdbelqdn5#

我知道这里我应该使用委托,但我的问题是:代表是否会更快?
这很简单:尝试并分享结果!
当1:1时,点对点委托关系可以比任何系统中的1:m发布和订阅更快。
是不是更快很难回答,因为这取决于环境.当侦听器不是很多并且发布者不需要搜索很多侦听器时,那么性能应该差不多,但是当有一百万个订阅者并且需要搜索它时,那么就可能出现延迟,帧速率降低.

9vw9lbht

9vw9lbht6#

委派会比通知快,但这两者都不是你所需要的。对于音频,你可能应该首先测量。如果你需要在更新UI之前更快地执行某个任务,那么你应该考虑通过GCD调度或NSOperation将一些处理任务移到另一个线程。

dfty9e19

dfty9e197#

调用委托只是一个方法调用,但是当使用通知时,需要在后台完成更多的工作来传递通知。考虑到这一点,委托会更快一些。
实时音频处理是一项复杂的任务,我倾向于认为委托的方法调用或发送通知产生的开销比音频处理代码少得多。

更新

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

相关问题