Я пытаюсь перенести большой [UInt8]
в [UInt16]
, и пока мое решение работает так:
//Function that converts [UInt8] into [UInt16]
func foo(arr: [UInt8])->[UInt16]{
//Split into even and odds
let even = stride(from: 0, to: arr.count, by: 2).map { arr[$0] }
let odd = stride(from: 1, to: arr.count, by: 2).map { arr[$0] }
//pair each even with the next odd
let paired=Array(zip(even, odd))
//reduce UInt8 pairs to UInt16
return paired.reduce([UInt16]()) { (acc, curr) -> [UInt16] in
let u16 = UnsafePointer([curr.0, curr.1]).withMemoryRebound(to: UInt16.self, capacity: 1) {
$0.pointee
}
var newV = acc
newV.append(u16)
return newV
}
}
Выше работает, но очень неэффективно. Функция Reduce - это место, где происходит большая часть времени вычислений.
Мне было интересно, можно ли напрямую использовать переопределение UnsafePointer.withMemoryRebound
.
Я попробовал:
let test : [UInt16] = UnsafePointer([UInt8(0), UInt8(1),UInt8(0), UInt8(1)]).withMemoryRebound(to: [UInt16].self, capacity: 2) {
$0.pointee
}
в результате:
Execution interrupted. Enter code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
Process 57635 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00007fff7d038d5f libobjc.A.dylib`objc_retain + 15
libobjc.A.dylib`objc_retain:
-> 0x7fff7d038d5f <+15>: movq (%rdi), %rax
0x7fff7d038d62 <+18>: movabsq $0x7ffffffffff8, %rcx ; imm = 0x7FFFFFFFFFF8
0x7fff7d038d6c <+28>: andq %rax, %rcx
0x7fff7d038d6f <+31>: testb $0x2, 0x20(%rcx)
Target 0: (repl_swift) stopped.
Может быть, я неправильно понял, как это должно работать. Это можно сделать? Есть ли лучший способ сделать это?