【问题标题】:Best Data get/set uint8 at index / Data masking最佳数据在索引/数据屏蔽处获取/设置 uint8
【发布时间】:2017-02-18 21:42:11
【问题描述】:

我正在尝试创建数据掩码函数。

我找到了两种方法:

  1. 使用数据下标

    • 很慢
  2. 从数据创建数组,改变它,然后将它转换回来

    • ~70 倍快
    • 使用 2 倍以上的内存

为什么数据下标这么慢? 有没有更好的方法在不复制内存的情况下在索引处获取/设置 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

【问题讨论】:

    标签: arrays swift optimization nsdata mask


    【解决方案1】:

    我无法确切告诉您为什么第一种方法(通过下标Data 值)如此缓慢。根据 Instruments 的说法,很多时间 是花在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 秒

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 2019-07-30
      • 2021-01-17
      • 2021-08-19
      • 2018-04-30
      相关资源
      最近更新 更多