我正在编写一个性能最重要的应用程序,我必须遍历一组工作站,这些工作站都有x坐标和y坐标。这是工作站的相关部分和位置:
struct Workstation {
let position: Position
}
struct Position {
let x, y: Int
func distance(to otherPosition: Position) -> Int {
return abs(self.x - otherPosition.x) + abs(self.y - otherPosition.y)
}
}
此特定情况下的目标是获得围绕所有工作站的矩形对角线长度的一半,但我稍后还必须进行其他一些计算(例如获取所有工作站的中心坐标)。
我提出了两种可能的解决方案(注意:layout.workstations
类型为Set<Workstation>
):
解决方案1
private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double {
var minX = Int.max
var maxX = Int.min
var minY = Int.max
var maxY = Int.min
for workstation in layout.workstations {
let pos = workstation.position
if pos.x < minX { minX = pos.x }
if pos.x > maxX { maxX = pos.x }
if pos.y < minY { minY = pos.y }
if pos.y > maxY { maxY = pos.y }
}
let minPosition = Position(x: minX, y: minY)
let maxPosition = Position(x: maxX, y: maxY)
return Double(minPosition.distance(to: maxPosition)) / 2
}
解决方案2
private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double {
let xValues = layout.workstations.map { $0.position.x }
let yValues = layout.workstations.map { $0.position.y }
guard let minX = xValues.min(), let maxX = xValues.max(), let minY = yValues.min(), let maxY = yValues.max() else {
fatalError("Minima or Maxima could not be determined!")
}
let minPosition = Position(x: minX, y: minY)
let maxPosition = Position(x: maxX, y: maxY)
return Double(minPosition.distance(to: maxPosition)) / 2
}
我的理解是解决方案1只在工作站中迭代一次,并且一次性填充所有需要的坐标变量。解决方案2具有更好的可读性,但必须迭代工作站集两次,结果数组四次,所以我想这更糟糕。所以我的问题是,如果我的假设是正确的,并且在这里有更有效的计算方法吗?
答案 0 :(得分:2)
首先,不要猜测哪一个更糟糕。运行它,并测量它。 (除了你的两个之外,还有一个选项,它使用内置的排序例程,然后查看结果的结尾。)
其次,如果要求访问此信息的速度始终尽可能快,则使用支持该要求的数据结构。查找初始集合的值一次,然后在每次添加元素时更新它们。每次添加新的Workstation
时,不要丢弃信息并反复进行相同的 N 比较,而只需执行四次 N 比较。然后,只要你需要,你就可以不间断地读取肢体。