在SWIFT中,有一种快速有效的方法可以使数组的所有值都改变符号(正值变为负值,反之亦然)?
例如:
let x: [Double] = [1.0, 2.0, -3.0, 4.0, -5.0]
Run Code Online (Sandbox Code Playgroud)
应该成为:
// x = [-1.0, -2.0, 3.0, -4.0, 5.0]
Run Code Online (Sandbox Code Playgroud)
如果您需要大型阵列的快速解决方案,那么您可以使用
cblas_dscal()Accelerate框架中的("标量乘法,双精度"):
import Accelerate
var x = [1.0, 2.0, -3.0, 4.0, -5.0]
cblas_dscal(Int32(x.count), -1.0, &x, 1)
print(x) // [-1.0, -2.0, 3.0, -4.0, 5.0]
Run Code Online (Sandbox Code Playgroud)
备注:也有cblas_sscal()对于Float阵列("单精度").
性能比较:这是一个非常简单的各种方法的性能比较:
let N = 1_000_000 // # of array elements
let R = 100 // # of repetitions
func test1() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
for i in x.indices { x[i] = -x[i] }
}
let time = Date().timeIntervalSince(start)
print("x[i] = -x[i] ", time)
}
func test2() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
for i in x.indices { x[i].negate() }
}
let time = Date().timeIntervalSince(start)
print("x[i].negate() ", time)
}
func test3() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
x = x.map { -$0 }
}
let time = Date().timeIntervalSince(start)
print("x.map { -$0 } ", time)
}
func test4() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
cblas_dscal(Int32(x.count), -1.0, &x, 1)
}
let time = Date().timeIntervalSince(start)
print("cblas_dscal ", time)
}
test1()
test2()
test3()
test4()
Run Code Online (Sandbox Code Playgroud)
结果(在3.5 GHz Intel iMac上,在Release配置中编译和运行:)
x[i] = -x[i] 0.0492849946022034
x[i].negate() 0.0635690093040466
x.map { -$0 } 0.285757005214691
cblas_dscal 0.0506410002708435
事实证明,cblas_dscal()与x[i] = -x[i]or 的显式循环速度大致相同x[i].negate(),但速度明显快于map()方法.
当然,结果可能在不同的硬件上或与其他阵列大小不同.
像往常一样,从您最熟悉的方法开始,如果事实证明性能至关重要,则寻找更快的方法.
| 归档时间: |
|
| 查看次数: |
836 次 |
| 最近记录: |