在索引/数据屏蔽时获取/设置uint8的最佳数据

时间:2017-02-18 21:42:11

标签: arrays swift optimization nsdata mask

我试图创建数据掩码功能。

我找到了两种方法:

  1. 使用数据下标

    • 非常慢
  2. 从数据创建数组,更改它然后将其转换回来

    • ~70倍快
    • 使用2倍以上的内存
  3. 为什么数据下载速度如此之慢? 有没有更好的方法来获取/设置uint8在索引而不重复内存?

    这是我的测试:

    var data = Data(bytes: [UInt8](repeating: 123, count: 100_000_000))
    
    let a = CFAbsoluteTimeGetCurrent()
    
    // data masking
    for i in 0..<data.count {
      data[i] = data[i] &+ 1
    }
    
    let b = CFAbsoluteTimeGetCurrent()
    
    // creating array
    var bytes = data.withUnsafeBytes {
      [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
    }
    for i in 0..<bytes.count {
      bytes[i] = bytes[i] &+ 1
    }
    data = Data(bytes: bytes)
    
    let c = CFAbsoluteTimeGetCurrent()
    print(b-a) // 8.8887130022049
    print(c-b) // 0.12415999174118
    

1 个答案:

答案 0 :(得分:1)

我无法确切地告诉你为什么第一种方法(通过订阅Data值)这么慢。据乐器说,很多时候 在调用方法时花费在objc_msgSend 基础NSMutableData对象。

但你可以改变字节而不复制 数据到数组:

data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in
    for i in 0..<data.count {
        bytes[i] = bytes[i] &+ 1
    }
}

比你的“复制到数组”方法更快。

在MacBook上我得到了以下结果:

  • 数据下载:7.15秒
  • 复制到阵列并返回:0.238秒
  • withUnsafeMutableBytes:0.0659秒