2016-07-15 3 views
0

Я пытался оптимизировать код, чтобы снизить использование моего процессора. Я переписал эти функции пару раз безрезультатно, ища некоторую помощь.Оптимизация кода Физика

63% времени, потраченного на мяч в ... линии, которая насчитывает не более 24 детей.

func totalMass() -> CGFloat { 
    var ret : CGFloat = 0 
    for ball in self.children as! [Ball] { 
     ret += ball.mass 
    } 
    return ret 
} 

почти 90% времени, затрачиваемого на если расстояние (питание ...) может быть более 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 
        } 
       } 
      } 
     } 
    } 

100% от времени, затраченного на закрывающей фигурной скобкой линии }) до третьего IF Постулаты

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

Печать в середине чего? Что еще объясняет, что FPS составляет 20 и ниже? – BARIIIIIIICODE

+1

Дайте [* this *] (http://stackoverflow.com/a/378024/23771). Он точно скажет вам, на что смотреть. –

+0

Возможно, мне не хватает того, что вы пытаетесь мне рассказать, похоже, что выборка обнаруживает проблему, которую я сделал, или, я думаю, – BARIIIIIIICODE

ответ

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 
        } 
       } 
      } 
     } 
    } 

к сожалению, наш выбор, чтобы получить тела в луче, точки или прямоугольника, но это будет получить нам все тело физики жгутов коробку радиуса. Затем мы используем формулу расстояния для лучшей точности.

+0

Спасибо, теперь это работает намного лучше. всего 40 до 10%. – BARIIIIIIICODE

+0

Что значит физика? он работает на SKView – BARIIIIIIICODE

+0

флаг showPhysics на skview, это ошибка в xcode. Если вы не видите физическую линию, выключите ее – Knight0fDragon

4

Вы знаете старую пилу о рыбаке? Дайте ему рыбу, вы кормите его на день. Научите его ловить рыбу, вы кормите его на всю жизнь.

Вместо того, чтобы сообщать вам, что исправить, позвольте мне объяснить, как вы можете найти ускорения, с помощью ручной выборки.

Предположим, что ваш код можно сделать быстрее (возможно, это возможно). Если вы это сделаете, это сэкономит немного времени, например, 20%. Это означает, что конкретная подробная деятельность, которую вы собираетесь оптимизировать, независимо от того, что она есть, фактически выполняет не менее 20% времени.

Он может выполнять большую часть времени, например, 40%. Просто ваша оптимизация не может избавиться от всего этого. Вы можете избавиться только от половины, поэтому вы можете получить только 20%.

Это означает, что если вы остановите его наугад и изучите все, что он делает подробно, и почему в этот момент времени есть 40% шанс, что вы увидите, что он делает то, что вы собираетесь оптимизировать, расточительная вещь.

Откуда вы знаете, что то, что вы видите, в то время как расточительно, занимает достаточно времени, чтобы беспокоиться о фиксации? Знаете, если вы видите это второе раз. Видя, что-то раз не говорит вам много - только то, что он принимает ненулевое время, но время второй вы видите его, вы не знаете, насколько он велик, но вы знаете, что это не маленький. Чем меньше раз вы пробуете перед тем, как увидеть его дважды, тем оно больше. Here are the statistics.

Итак, если вы собираетесь сэкономить 20%, а если оно выполняется в течение 40% времени, сколько образцов вам нужно, прежде чем смотреть дважды? В среднем 2/.4, что составляет 5 выборок. Если вы возьмете 10 образцов, сколько раз вы можете их увидеть? Четыре. Если вы возьмете 10 образцов, то какова вероятность того, что вы не будете смотреть его более одного раза? 4.5% Если вы возьмете 20 образцов, какова вероятность, что вы это пропустите? Практически нулевая.

Таким образом, это сила ручной выборки. Вы можете увидеть точную информацию о том, что делает программа, и почему она это делает. Вот что профайлеры не говорят вам. Они берут больше образцов, а затем объединяют их вместе в временные числа, поэтому вы можете увидеть так называемый «горячий код», но вы угадали, что вы можете сделать, чтобы исправить это. Ручное исследование небольшого количества образцов, в деталях, наведение каждого вашего интеллектуала программиста на понимание каждого из них, сообщает вам ровно.

Вот почему this post, в отличие от общей мудрости, имеет так много голосов. Вы получите больше скорости.

+0

В то время как богатство знаний и ценят это, я считаю, что я сделал это. Я не просто взял один экземпляр запусков, у меня их несколько, и кажется, что одни и те же функции подвергаются насилию. Я заменил большую графику меньшими удаленными большими узлами, ничего не изменилось. – BARIIIIIIICODE

+0

@BARIIIIIIICODE: Посмотрели ли вы на точные строки, выполненные в образцах, и данные, над которыми они работали? То же самое делалось с теми же данными, что и в предыдущее время? Был ли «за мяч в себе», как! [Ball] 'непосредственно в стеке в нескольких образцах? Это выглядит подозрительно для меня. Возможно, следует рассмотреть возможность разворачивания. Это то, что вам нужно сделать - посмотрите на каждый образец с подозрительным глазом. Что можно сделать, чтобы уменьшить/устранить его? –

+0

Теперь я не эксперт, но из того, что я вижу, да. Вышеупомянутые функции жизненно важны для того, чтобы игра вызывалась от начала до конца без остановки. «for ball» всегда ищет шары, потому что общая масса должна быть всегда известна. Функция для массы при вызове тратит почти все свое время на 'for ball' каждый раз. Я тестировал его много раз. – BARIIIIIIICODE

Смежные вопросы