与 map 方法相比,为什么这种 for 循环方法这么慢?
why this for loop approach is so slow compared with the map approach?
我在 Playground 中测试了我的代码,但正如讨论所指出的那样,Playground 是调试配置,一旦我将所有这些代码放入真实应用程序 运行,它们就不会很大的不同。以前不知道这个debug/release事情
Swift性能相关的问题,我需要遍历图像的像素偏移量,首先我是这样尝试的。
func p1() -> [[Int]]{
var offsets = [[Int]]()
for row in 0..<height {
var rowOffset = [Int]()
for col in 0..<width {
let offset = width * row + col
rowOffset.append(offset)
}
offsets.append(rowOffset)
}
return offsets
}
但是很慢,我搜索了一些代码片段,通过偏移量循环:
func p2() -> [[Int]]{
return (0..<height).map{ row in
(0..<width).map { col in
let offset = width * row + col
return offset
}
}
}
所以我测试了如果我使用函数p1和p2循环遍历height = 128和width = 128的图像,p1比p2慢18倍,为什么p1比p2慢?我也想知道是否有其他更快的方法来完成这项任务?
map
方法更快的最明显原因是因为 map
预先分配数组容量(因为它知道结果数组中有多少元素)。您也可以通过在数组上调用 ary.reserveCapacity(n)
在您的代码中执行此操作,例如
func p1() -> [[Int]]{
var offsets = [[Int]]()
offsets.reserveCapacity(height) // NEW LINE
for row in 0..<height {
var rowOffset = [Int]()
rowOffset.reserveCapacity(width) // NEW LINE
for col in 0..<width {
let offset = width * row + col
rowOffset.append(offset)
}
offsets.append(rowOffset)
}
return offsets
}
我在 Playground 中测试了我的代码,但正如讨论所指出的那样,Playground 是调试配置,一旦我将所有这些代码放入真实应用程序 运行,它们就不会很大的不同。以前不知道这个debug/release事情
Swift性能相关的问题,我需要遍历图像的像素偏移量,首先我是这样尝试的。
func p1() -> [[Int]]{
var offsets = [[Int]]()
for row in 0..<height {
var rowOffset = [Int]()
for col in 0..<width {
let offset = width * row + col
rowOffset.append(offset)
}
offsets.append(rowOffset)
}
return offsets
}
但是很慢,我搜索了一些代码片段,通过偏移量循环:
func p2() -> [[Int]]{
return (0..<height).map{ row in
(0..<width).map { col in
let offset = width * row + col
return offset
}
}
}
所以我测试了如果我使用函数p1和p2循环遍历height = 128和width = 128的图像,p1比p2慢18倍,为什么p1比p2慢?我也想知道是否有其他更快的方法来完成这项任务?
map
方法更快的最明显原因是因为 map
预先分配数组容量(因为它知道结果数组中有多少元素)。您也可以通过在数组上调用 ary.reserveCapacity(n)
在您的代码中执行此操作,例如
func p1() -> [[Int]]{
var offsets = [[Int]]()
offsets.reserveCapacity(height) // NEW LINE
for row in 0..<height {
var rowOffset = [Int]()
rowOffset.reserveCapacity(width) // NEW LINE
for col in 0..<width {
let offset = width * row + col
rowOffset.append(offset)
}
offsets.append(rowOffset)
}
return offsets
}