Что является более продуктивным в рендере OpenGL l oop: оператор if или лямбда? - PullRequest
1 голос
/ 03 марта 2020

Когда начинается рендеринг игры, часть алгоритма изменяется (обработка нажатия на экран).

Есть два варианта. 1. Используйте оператор «если»:

public class Leve1 implements GLSurfaceView.Renderer {
  private boolean isLoadGame = false;
  public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    ...
    isLoadGame = true; // game is now loaded
  }
  // this method is called often in the render loop
  public void setPassXY(float x, float y) {
    if (isLoadGame) {
      ... // perform algorithm 
    }
  }
}

2. Используйте лямбду (без «если»):

public class Leve1 implements GLSurfaceView.Renderer {
  // when the game is not loaded yet use the empty method body
  private PressXYInterface<Float, Float> pressXY = (pressX, pressY) -> {};
  public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    ...
    pressXY = (passX, passY) -> { 
      ... // game is now loaded - add algorithm
    };
  }
  // this method is called often in the render loop
  public void setPassXY(float x, float y) {
    pressXY.invoke(x, y); // perform algorithm
  }
}

@FunctionalInterface
public interface PressXYInterface<T, U> {
  void invoke(T x, U y);
}

Вопрос: какой подход лучше использовать с точки зрения производительности?

1 Ответ

2 голосов
/ 03 марта 2020

TL; DR - нет ни одного правильного ответа. Это зависит от множества факторов. Сравнительный анализ вашего реального приложения - единственный способ получить надежный ответ.


Вот некоторые из вопросов:

С одной стороны, версия, использующая lambdas сохраняет оператор if.

С другой стороны, версия, использующая вызов метода, потенциально может быть встроена компилятором JIT. (Эти лямбда-вызовы не могут быть встроенными, потому что в разные моменты времени сайт вызова может вызывать разные лямбды.)

С другой стороны, если // perform algorithm достаточно сложный, он будет слишком большим для встроенного.

С другой стороны, если algorithm слишком велик для встроенного, возможно стоимость теста if будет незначительной.

С другой стороны С другой стороны, тест if может оказаться дешевле, чем вы думаете. Например:

  • Если код скомпилирован JIT после перехода в состояние isLoadGame == true, то статистика может дать указание JIT-компилятору оптимизировать его в случае успеха теста.
  • (Аппаратное) предсказание ветви может приспособиться к модальному поведению этого теста.

С другой стороны, мне не ясно, какие версии должны делать простые вызовы или виртуальные вызовы. Или может ли JIT-компилятор оптимизировать виртуальные вызовы. Я просто не знаю. (Изучение байт-кодов дало бы частичный ответ.)

Тогда возникают проблемы с различными версиями JIT-компилятора, различными аппаратными ISA, различными аппаратными реализациями.

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

Это также означает, что микробанкинг вряд ли будет полезным. Многие из вышеперечисленных факторов будут критически зависеть от реального кода приложения и способа запуска приложения. Вам нужно будет сравнить реальное приложение, чтобы получить значимые результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...