Проблема производительности с конечным автоматом на Android - PullRequest
0 голосов
/ 01 декабря 2011

Не уверен, что это проблема Android, я разработчик C ++, пытаюсь написать Java:)

Проблема вкратце .. Я заменил длинный и сложный в обслуживании корпус переключателя на конечный автомат, и в то время как базовый код такой же, я получаю потеря производительности около 20%

Несколько более подробных объяснений: Я создал приложение andriod на основе SurfaceView на основе примера кода из SDK после расширения моего приложения я обнаружил, что в моем игровом цикле сохраняются длинные переключатели

как правило, мой скелет приложения выглядит так (во многих случаях)

class myView extends SurfaceView implements SurfaceHolder.Callback {
   public void update() {
      switch (_state) {
         case MENU: ... break;
         case LOAD: ... break;
         case RUN: ... break;
         ...
      }
   }

   public void draw(Canvas c) {
      switch (_state) {
         case MENU: ... break;
         case LOAD: ... break;
         case RUN: ... break;
         ...
      }
   }

   public boolean onTouchEvent(MotionEvent event) {
      switch (_state) {
         case MENU: ... break;
         case LOAD: ... break;
         case RUN: ... break;
         ...
      }
   }
}

Поэтому я решил провести рефакторинг своего кода и внедрил простой конечный автомат (FSM)

public class StateMachine {

    public State state;
    private myView context;

    public StateMachine(myView view) {
        context = view;
    state = new StateMainMenu();
}

    interface State {
        public void update();
        public void draw(Canvas canvas);
        public boolean onTouchEvent(MotionEvent event);
    }

    class StateMainMenu implements State {

    public StateMainMenu() { ... }

    @Override
    public void update() { 
            ... 
            if (windOfChange) {
               state = new StateTheNextState();
            }
        }

        @Override
    public void draw(Canvas canvas) { ... }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
            synchronized (_thread.getSurfaceHolder()) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: ... break;
                    ...
                }
                return true;
            }
        }
    }
}

и в myView используется вот так

class myView extends SurfaceView implements SurfaceHolder.Callback {

    private StateMachine stateMachine = new StateMachine(this);

    public void update() {
        stateMachine.state.update();
    }

    public void draw(Canvas c) {
        stateMachine.state.draw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        synchronized (_thread.getSurfaceHolder()) {
            return stateMachine.state.onTouchEvent(event);
        }
    }
}

Пока внутри штатов я делаю именно то, что делал раньше такое же количество созданных объектов и тот же код Запустив мое приложение, я получаю примерно на 20% меньше кадров ...

Есть идеи, почему? или что я делаю не так?

1 Ответ

1 голос
/ 01 декабря 2011

Мой совет - профилировать выполнение вашего приложения с помощью Traceview , чтобы определить, какая его часть действует как узкое место.Без этого это немного похоже на стрельбу в темноте.Я бы поставил свои 2 цента на синхронизированные блоки.

...