使用 getter 时 UnsafeMutableBufferPointer 很慢

Posted

技术标签:

【中文标题】使用 getter 时 UnsafeMutableBufferPointer 很慢【英文标题】:UnsafeMutableBufferPointer slow when using getter 【发布时间】:2017-06-21 13:12:30 【问题描述】:

我有一个带有自定义 AURenderCallback 的 AVAudioEngine。当我运行引擎时,cpu 会飙升,这似乎与 UnsafeMutableBufferPointer.getter 和 .setter 操作有关:

func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus 

    let blI = UnsafeMutableAudioBufferListPointer(ioData)

    let numSamples = Int((blI?[0].mDataByteSize)! / UInt32(MemoryLayout<Float32>.stride))

    for input in 0 ..< blI!.count

        let bI = blI?[input]

        guard let inputData = bI?.mData else 

            //assert(false)

            return kAudioUnitErr_Uninitialized
        

        let samplesBI = UnsafeMutablePointer<Float32>(inputData.assumingMemoryBound(to: Float32.self))

        let samplesI = UnsafeMutableBufferPointer<Float32>(start: samplesBI, count: numSamples)

        for sampleIndex in 0 ..< samplesI.count 

            samplesI[sampleIndex] *= 0.5
        

    

    return noErr

什么会导致获取和设置指针数据的这种低效行为?因为它正在处理音频样本,所以效率低下会导致音频信号出现断断续续的情况。

【问题讨论】:

【参考方案1】:

你可以跳过 UnsafeMutableBufferPointer() 调用,直接索引样本指针:

let bufferListPtr = UnsafeMutableAudioBufferListPointer(ioData)
...
let mBuffer : AudioBuffer = bufferListPtr[0]
let count = Int(mBuffer.mDataByteSize) / yourSampleSizeInBytes
let dataPointer = UnsafeMutableRawPointer(mBuffer.mData)
if let dptr = dataPointer 
    let sampleArray = dptr.assumingMemoryBound(to: yourSampleType.self)
    for i in 0..<(count) 
        let x = sampleArray[i]
        let y = myModifySample( x )   
        sampleArray[i] =  y 
    

我将 Int16 用于 mySampleType(大小 = 2 字节),但它也适用于 4 字节类型 Float。

直接使用原始内存指针可能会避免一些缓冲区 getter/setter 效率低下(以及验证,所以要小心!)。

【讨论】:

以上是关于使用 getter 时 UnsafeMutableBufferPointer 很慢的主要内容,如果未能解决你的问题,请参考以下文章

生成Getter时如何忽略注释?

如何解决:使用自定义视图实现双向数据绑定时“找不到属性'android:text'的getter”?

“未使用属性访问结果-getter 不应用于副作用”检查文本字段是不是为空时出错 [关闭]

@JsonIgnore 和 @Getter 注解

在颤振中使用提供者时,getter 被调用为 null

如果wen可以定义公共属性,Angular2为啥要使用getter