【发布时间】:2021-06-14 00:04:11
【问题描述】:
我有以下代码。它包含需要尽可能快的getPointAndPos 函数:
struct Point {
let x: Int
let y: Int
}
struct PointAndPosition {
let pnt: Point
let pos: Int
}
class Elements {
var points: [Point]
init(points: [Point]) {
self.points = points
}
func addPoint(x: Int, y: Int) {
points.append(Point(x: x, y: y))
}
func getPointAndPos(pos: Int) -> PointAndPosition? {
guard pos >= 0 && points.count > pos else {
return nil
}
return PointAndPosition(pnt: points[pos], pos: pos)
}
}
但是,由于 Swift 内存管理,它一点也不快。我曾经使用字典,但情况更糟。该功能在应用程序中被大量使用,因此它是现在的主要瓶颈。以下是getPointAndPos 函数的分析结果:
如您所见,从数组中获取一个项目大约需要 4.5 秒,这太疯狂了。我尝试遵循我能找到的所有性能优化技术,即:
- 使用数组代替字典
- 使用简单类型作为数组元素(在我的例子中是结构)
它有所帮助,但还不够。考虑到在添加元素后我不会从数组中更改元素,有没有办法进一步优化它?
更新 #1:
按照建议,我用 [PointAndPosition] 替换了 [Point] 数组并删除了可选项,这使代码速度提高了 6 倍。另外,根据要求提供使用getPointAndPos函数的代码:
private func findPoint(el: Elements, point: PointAndPosition, curPos: Int, limit: Int, halfLevel: Int, incrementFunc: (Int) -> Int) -> PointAndPosition? {
guard curPos >= 0 && curPos < el.points.count else {
return nil
}
// get and check point here
var next = curPos
while true {
let pnt = el.getPointAndPos(pos: next)
if checkPoint(pp: point, pnt: pnt, halfLevel: halfLevel) {
return pnt
} else {
next = incrementFunc(next)
if (next != limit) {
continue //then findPoint next limit incrementFunc
}
break
}
}
return nil
}
当前的实现要快得多,但理想情况下我需要让它比现在快 30 倍。不确定它是否可能。这是最新的分析结果:
【问题讨论】:
-
刚试过。它增加了性能下降。看起来更好,但速度较慢。
标签: arrays swift performance