我一直在尝试优化代码以降低我的CPU使用率。我已经重写了这些功能几次无济于事,寻求一些帮助。
63%的时间花在球上......最多只有24个孩子。
func totalMass() -> CGFloat {
var ret : CGFloat = 0
for ball in self.children as! [Ball] {
ret += ball.mass
}
return ret
}
将近90%的时间用于if距离(食物......),可以有超过800件食物'一次。
func randomMove() {
confidenceLevel = 0
if let b = self.children.first as! Ball? {
if b.physicsBody?.velocity == CGVector(dx: 0, dy: 0) {
//print("a")
self.move(randomPosition())
} else if b.position.x + b.radius > 1950 || b.position.x - b.radius < -1950 {
//print("here", b.position.x, b.radius)
self.move(randomPosition())
} else if b.position.y + b.radius > 1950 || b.position.y - b.radius < -1950 {
//print("there")
self.move(randomPosition())
} else {
// Keep moving
let scene : GameScene = self.scene as! GameScene
for food in scene.foodLayer.children as! [Food] {
if distance (food.position, p2: self.centerPosition()) < b.radius * 5 {
self.move(food.position)
return
}
}
}
}
}
在第三个IF声明之前在结束花括号线}上花费的时间的100%
override func didSimulatePhysics() {
world.enumerateChildNodesWithName("//ball*", usingBlock: {
node, stop in
let ball = node as! Ball
ball.regulateSpeed()
if let body = ball.physicsBody {
if (body.velocity.speed() > 0.01) {
ball.zRotation = body.velocity.angle() - self.offset
}
}
})
if let p = currentPlayer {
centerWorldOnPosition(p.centerPosition())
} else if playerLayer.children.count > 0 {
let p = playerLayer.children.first! as! Player
centerWorldOnPosition(p.centerPosition())
} else {
centerWorldOnPosition(CGPoint(x: 0, y: 0))
}
}
答案 0 :(得分:4)
你知道关于渔夫的老看见了吗? 给他一条鱼,喂他一天。 教他钓鱼,你喂他一辈子。
不要告诉你要修复什么,让我解释一下如何通过手动采样找到加速比。
让我们假设您的代码可以更快(可能)。如果你这样做,它会节省一些时间,比如20%。 这意味着您要优化的具体详细活动,无论它是什么,实际上都在执行至少 20%的时间。
可能会执行更大比例的时间,例如40%。 只是你的优化可能无法摆脱所有这些。 你可能只能摆脱一半,所以你只能净20%。
这意味着如果你随机停止它,并在那个时间点检查它正在做的所有事情以及为什么,那么你有40%的机会看到它做你想做的事情要优化,浪费的东西。
你怎么知道你看到的是什么,虽然浪费,但是有足够的时间来解决问题? 你知道,如果你看到第二时间。 看到一次的东西并没有告诉你太多 - 只需要非零时间, 但是你看到第二时间,你不知道它有多大,但你确实知道它不小。 在看到它两次之前采样的次数越少,它就越大。 Here are the statistics.
因此,如果它将节省20%,并且如果它在40%的时间内执行,那么在看到它之前需要多少个样本? 平均为2 / .4,即5个样本。 如果你取10个样品,你能看到多少次?四。 如果您采取10个样本,那么不会多次查看它的概率是多少? 4.5% 如果你拿20个样本,你会错过它的概率是多少?实际上为零。
所以这是手动采样的力量。 您可以看到程序正在做什么的精确细节以及它为什么这样做。 这是分析师不告诉你的。 他们采取了更多的样本,然后将它们拼凑成时间数字,这样你就可以看到所谓的“热门代码”了,但是你还在猜测你可以做些什么来修复它。 详细地手动检查少量样本,让所有程序员的智力理解每一个,告诉你完全。
这就是为什么this post虽然与普遍的智慧相反,却有如此多的选票。 你可以获得更快的速度。
答案 1 :(得分:1)
以这种方式使用距离公式可能是一项昂贵的操作,如果你不需要实际距离,我建议你使用距离平方
func randomMove() {
confidenceLevel = 0
if let b = self.children.first as! Ball? {
if b.physicsBody?.velocity == CGVector(dx: 0, dy: 0) {
//print("a")
self.move(randomPosition())
} else if b.position.x + b.radius > 1950 || b.position.x - b.radius < -1950 {
//print("here", b.position.x, b.radius)
self.move(randomPosition())
} else if b.position.y + b.radius > 1950 || b.position.y - b.radius < -1950 {
//print("there")
self.move(randomPosition())
} else {
// Keep moving
let bRadiusSqr = b.radius * 5 * b.radius * 5
let selfPosition = self.centerPosition()
let scene : GameScene = self.scene as! GameScene
var moved = false
scene.foodLayer.children.forEach() {
food in
if(!moved)
{
let diffX = food.position.x - selfPosition.x
let diffY = food.position.y - selfPosition.y
if diffX * diffX + diffY * diffY < bRadiusSqr {
self.move(food.position)
moved = true
}
}
}
}
}
}
仔细检查每一种食物是一种不好的方法,而不是尝试一下:
func randomMove() {
confidenceLevel = 0
if let b = self.children.first as! Ball? {
if b.physicsBody?.velocity == CGVector(dx: 0, dy: 0) {
//print("a")
self.move(randomPosition())
} else if b.position.x + b.radius > 1950 || b.position.x - b.radius < -1950 {
//print("here", b.position.x, b.radius)
self.move(randomPosition())
} else if b.position.y + b.radius > 1950 || b.position.y - b.radius < -1950 {
//print("there")
self.move(randomPosition())
} else {
// Keep moving
let bRadiusSqr = b.radius * 5 * b.radius * 5
let selfPosition = self.centerPosition()
let scene : GameScene = self.scene as! GameScene
let world : SKPhysicsWorld = scene.physicsWorld
world.enumerateBodiesInRect(CGRectMake(selfPosition.x - b.radius, selfPosition.y - b.radius,bradius*2,bradius*2))
{
body,stop in
guard let food = body.node as? Food else { return}
let diffX = food.position.x - selfPosition.x
let diffY = food.position.y - selfPosition.y
if diffX * diffX + diffY * diffY < bRadiusSqr {
self.move(food.position)
stop = true
}
}
}
}
}
不幸的是,我们的选择是在光线,点或矩形中获取物体,但是这将使我们所有的物理体都具有半径的盒子。我们之后使用距离公式以获得更好的准确性。